{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第12课：完全基于情感词典的文本情感分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SnowNLP 主要可以进行中文分词、词性标注、情感分析、文本分类、转换拼音、繁体转简体、提取文本关键词、提取摘要、分割句子、文本相似等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SnowNLP 对情感的测试值为0到1，值越大，说明情感倾向越积极"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from snownlp import SnowNLP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9999619413786875"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "SnowNLP(u'本本已收到，体验还是很好，功能方面我不了解，只看外观还是很不错很薄，很轻，也有质感。').sentiments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03199178977263639"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# zhongpin\n",
    "SnowNLP(u'屏幕分辨率一般，送了个极丑的鼠标。').sentiments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0038967116164347892"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "SnowNLP(u'很差的一次购物体验，细节做得极差了，还有发热有点严重啊，散热不行，用起来就是烫得厉害，很垃圾！！！').sentiments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# from snownlp import sentiment\n",
    "# sentiment.train('neg.txt', 'pos.txt')\n",
    "# sentiment.save('sentiment.marshal')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1、加载玻森情感词典；\n",
    "2、jieba 分词；\n",
    "3、获取句子得分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import jieba"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# df = pd.read_table(\"bosonnlp//BosonNLP_sentiment_score.txt\",sep= \" \",names=['key','score'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# key = df['key'].values.tolist()\n",
    "# score = df['score'].values.tolist()\n",
    "# def getscore(line):\n",
    "#     segs = jieba.lcut(line)  #分词\n",
    "#     score_list  = [score[key.index(x)] for x in segs if(x in key)]\n",
    "#     return  sum(score_list)  #计算得分\n",
    "# line = \"今天天气很好，我很开心\"\n",
    "# print(round(getscore(line),2))\n",
    "\n",
    "# line = \"今天下雨，心情也受到影响。\"\n",
    "# print(round(getscore(line),2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# import pytreebank"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type='text/javascript' >(function(){function t(){function f(a){var b={lightness:function(c){return c==null?a[0]:!isNaN(c)?f([a[0]+c,a[1],a[2]]):null},chroma:function(c){if(c==null)return Math.sqrt(a[1]*a[1]+a[2]*a[2]);if(!isNaN(c)){var c=Math.sqrt(a[1]*a[1]+a[2]*a[2])+c,b=Math.atan2(a[2],a[1]);c<0&&(c=0);return f(l([a[0],c,b]))}return null},hue:function(c){if(c==null)return Math.atan2(a[2],a[1])*180/Math.PI;if(!isNaN(c)){var b=Math.sqrt(a[1]*a[1]+a[2]*a[2]),c=Math.atan2(a[2],a[1])+c*Math.PI/180;return f(l([a[0],b,c]))}return null},\n",
       "a:function(c){return c==null?a[1]:!isNaN(c)?f([a[0],a[1]+c,a[2]]):null},b:function(c){return c==null?a[2]:!isNaN(c)?f([a[0],a[1],a[2]+c]):null}};b.X=function(a){return b.xyz().X(a)};b.Y=function(a){return b.xyz().Y(a)};b.Z=function(a){return b.xyz().Z(a)};b.x=function(a){return b.xyz().x(a)};b.y=function(a){return b.xyz().y(a)};b.r=function(a){return b.rgb().r(a)};b.g=function(a){return b.rgb().g(a)};b.b=function(a){return b.rgb().b(a)};b.hex=function(){return b.rgb().hex()};b.lab=function(){return f(a)};\n",
       "b.xyz=function(){return g(i(a))};b.rgb=function(){return h(m(i(a)))};b.toString=function(){return b.rgb().hex()};return b}function l(a){var b=a[0],c=a[1]*Math.cos(a[2]),a=a[1]*Math.sin(a[2]);return[b,c,a]}function g(a){var b={};b.lightness=function(a){return b.lab().lightness(a)};b.chroma=function(a){return b.lab().chroma(a)};b.hue=function(a){return b.lab().hue(a)};b.x=function(c){if(c==null)return j(a)[0];if(!isNaN(c)){var b=j(a);return g(n([b[0]+c,b[1],b[2]]))}return null};b.y=function(c){if(c==\n",
       "null)return j(a)[1];if(!isNaN(c)){var b=j(a);return g(n([b[0],b[1]+c,b[2]]))}return null};b.X=function(b){return b==null?a[0]:!isNaN(b)?g([a[0]+b,a[1],a[2]]):null};b.Y=function(b){return b==null?a[1]:!isNaN(b)?g([xyx[0],a[1]+b,a[2]]):null};b.Z=function(b){return b==null?a[2]:!isNaN(b)?g([xyx[0],a[1],a[2]+b]):null};b.r=function(a){return b.rgb().r(a)};b.g=function(a){return b.rgb().g(a)};b.b=function(a){return b.rgb().b(a)};b.hex=function(){return b.rgb().hex()};b.lab=function(){return f(p(a))};b.xyz=\n",
       "function(){return g(a)};b.rgb=function(){return h(m(a))};b.toString=function(){return b.rgb().hex()};return b}function j(a){var b=a[0],c=a[1],d=a[2],a=b/(b+c+d),b=c/(b+c+d);c==0&&(a=0.312727,b=0.329023);return[a,b,c]}function n(a){var b=a[0],c=a[1],a=a[2],d=a*b/c,b=a*(1-b-c)/c;c==0&&(b=d=0);return[d,a,b]}function h(a){var b={};b.lightness=function(a){return b.lab().lightness(a)};b.chroma=function(a){return b.lab().chroma(a)};b.hue=function(a){return b.lab().hue(a)};b.X=function(a){return b.xyz().X(a)};\n",
       "b.Y=function(a){return b.xyz().Y(a)};b.Z=function(a){return b.xyz().Z(a)};b.x=function(a){return b.xyz().x(a)};b.y=function(a){return b.xyz().y(a)};b.r=function(b){return b==null?a[0]:!isNaN(b)?h([a[0]+b,a[1],a[2]]):null};b.g=function(b){return b==null?a[1]:!isNaN(b)?h([a[0],a[1]+b,a[2]]):null};b.b=function(b){return b==null?a[2]:!isNaN(b)?h([a[0],a[1],a[2]+b]):null};b.hex=function(){var b=Math.min(1,Math.max(0,a[0])),d=Math.min(1,Math.max(0,a[1])),e=Math.min(1,Math.max(0,a[2])),b=Math.round(b*255).toString(16),\n",
       "d=Math.round(d*255).toString(16),e=Math.round(e*255).toString(16);b.length<2&&(b=\"0\"+b);d.length<2&&(d=\"0\"+d);e.length<2&&(e=\"0\"+e);return\"#\"+b+d+e};b.lab=function(){return f(p(q(a)))};b.xyz=function(){return g(q(a))};b.rgb=function(){return h(a)};b.toString=function(){return b.rgb().hex()};return b}function o(a){a.substr(0,1)==\"#\"&&(a=a.substr(1));a.substr(0,2)==\"0x\"&&(a=a.substr(2));return a.length==6?[parseInt(a.substr(0,2),16)/255,parseInt(a.substr(2,2),16)/255,parseInt(a.substr(4,2),16)/255]:\n",
       "a.length==3?[parseInt(a.substr(0,1),16)/15,parseInt(a.substr(1,1),16)/15,parseInt(a.substr(2,1),16)/15]:null}function k(a){var b={hue:function(b){if(b==null)return\"\";return!isNaN(b)?(b=a[0]+b,b<=Math.PI&&(b+=Math.PI),b>Math.PI&&(b-=Math.PI),k([b,a[1],a[2]])):null},value:function(b){return b==null?a[1]:!isNaN(b)?k([a[0],a[1]+b,a[2]]):null},chroma:function(b){return b==null?a[2]:!isNaN(b)?k([a[0],a[1],a[2]+b]):null},lab:function(){return f([0,0,0])},xyz:function(){return g(i([0,0,0]))},rgb:function(){return h(m(i([0,\n",
       "0,0])))}};b.toString=function(){return b.rgb().hex()};return b}function r(a){var b={blue:\"#1f77b4\",lightblue:\"#aec7e8\",orange:\"#ff7f0e\",lightorange:\"#ffbb78\",green:\"#2ca02c\",lightgreen:\"#98df8a\",red:\"#d62728\",lightred:\"#ff9896\",purple:\"#9467bd\",lightpurple:\"#c5b0d5\",brown:\"#8c564b\",lightbrown:\"#c49c94\",pink:\"#e377c3\",lightpink:\"#f7b6d2\",grey:\"#7f7f7f\",gray:\"#7f7f7f\",lightgrey:\"#c7c7c7\",lightgray:\"#c7c7c7\",yellow:\"#bcbd22\",lightyellow:\"#dbdb8d\",cyan:\"#17becf\",lightcyan:\"#9edae5\"},a=a.replace(/[^A-Za-z]/g,\n",
       "\"\").toLowerCase();return b.hasOwnProperty(a)?h(o(b[a])):null}function s(a){var b={lightblue:\"0xA6CEE3\",blue:\"0x1F78B4\",lightgreen:\"0xB2DF8A\",green:\"0x33A02C\",lightred:\"0xFB9A99\",red:\"0xE31A1C\",lightorange:\"0xFDBF6F\",orange:\"0xFF7F00\",lightpurple:\"0xCAB2D6\",purple:\"0x6A3D9A\"},a=a.replace(/[^A-Za-z]/g,\"\").toLowerCase();return b.hasOwnProperty(a)?h(o(b[a])):null}function q(a){function b(a){return a<=0.04045?a/12.92:Math.pow((a+0.055)/1.055,2.4)}var c=b(a[0]),d=b(a[1]),a=b(a[2]);return[0.4124564*c+0.3575761*\n",
       "d+0.1804375*a,0.2126729*c+0.7151522*d+0.072175*a,0.0193339*c+0.119192*d+0.9503041*a]}function m(a){function b(a){return a<=0.0031308?12.92*a:1.055*Math.pow(a,1/2.4)-0.055}var c=a[0],d=a[1],a=a[2],e=-0.969266*c+1.8760108*d+0.041556*a,f=0.0556434*c-0.2040259*d+1.0572252*a;return[b(3.2404542*c-1.5371385*d-0.4985314*a),b(e),b(f)]}function p(a){function b(a){return a>c?Math.pow(a,1/3):(d*a+16)/116}var c=216/24389,d=24389/27,e=a[1]/1,f=a[2]/1.08883,a=b(a[0]/0.95047),e=b(e),f=b(f);return[116*e-16,500*(a-\n",
       "e),200*(e-f)]}function i(a){function b(a){return Math.pow(a,3)>c?Math.pow(a,3):(116*a-16)/d}var c=216/24389,d=24389/27,e=a[0],f=(e+16)/116,g=f-a[2]/200,a=b(a[1]/500+f),e=e>d*c?Math.pow((e+16)/116,3):e/d,g=b(g);return[a*0.95047,e*1,g*1.08883]}return{lab:function(a,b,c){return f([a,b,c])},lch:function(a,b,c){c=c*Math.PI/180;return f(l([a,b,c]))},xyz:function(a,b,c){return g([a,b,c])},xyy:function(a,b,c){return g(n([a,b,c]))},rgb:function(a,b,c){return h([a,b,c])},hex:function(a){return h(o(a))},munsell:function(a,\n",
       "b,c){return k([0,b,c])},$:function(a,b){return b==null||b.toLowerCase()==\"stone\"?r(a):b.toLowerCase()==\"brewer\"?s(a):b.toLowerCase()==\"xkcd\"?null:b.toLowerCase()==\"wcs\"?null:null},stone:function(a){return r(a)},brewer:function(a){return s(a)}}}typeof c3==\"undefined\"&&(c3=t())})();\n",
       "</script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script type='text/javascript' >(function(){function cs(){return\"circle\"}function cr(){return 64}function cq(a,b){var c=(a.ownerSVGElement||a).createSVGPoint();if(cp<0&&(window.scrollX||window.scrollY)){var d=d3.select(document.body).append(\"svg:svg\").style(\"position\",\"absolute\").style(\"top\",0).style(\"left\",0),e=d[0][0].getScreenCTM();cp=!e.f&&!e.e,d.remove()}cp?(c.x=b.pageX,c.y=b.pageY):(c.x=b.clientX,c.y=b.clientY),c=c.matrixTransform(a.getScreenCTM().inverse());return[c.x,c.y]}function co(a){return function(){var b=a.apply(this,arguments),c=b[0],d=b[1]+bA;return[c*Math.cos(d),c*Math.sin(d)]}}function cn(a){return[a.x,a.y]}function cm(a){return a.endAngle}function cl(a){return a.startAngle}function ck(a){return a.radius}function cj(a){return a.target}function ci(a){return a.source}function ch(a){return function(b,c){return a[c][1]}}function cg(a){return function(b,c){return a[c][0]}}function cf(a){function i(f){if(f.length<1)return null;var i=bH(this,f,b,d),j=bH(this,f,b===c?cg(i):c,d===e?ch(i):e);return\"M\"+g(a(j),h)+\"L\"+g(a(i.reverse()),h)+\"Z\"}var b=bI,c=bI,d=0,e=bJ,f=\"linear\",g=bK[f],h=.7;i.x=function(a){if(!arguments.length)return c;b=c=a;return i},i.x0=function(a){if(!arguments.length)return b;b=a;return i},i.x1=function(a){if(!arguments.length)return c;c=a;return i},i.y=function(a){if(!arguments.length)return e;d=e=a;return i},i.y0=function(a){if(!arguments.length)return d;d=a;return i},i.y1=function(a){if(!arguments.length)return e;e=a;return i},i.interpolate=function(a){if(!arguments.length)return f;g=bK[f=a];return i},i.tension=function(a){if(!arguments.length)return h;h=a;return i};return i}function ce(a){var b,c=-1,d=a.length,e,f;while(++c<d)b=a[c],e=b[0],f=b[1]+bA,b[0]=e*Math.cos(f),b[1]=e*Math.sin(f);return a}function cd(a){return a.length<3?bL(a):a[0]+bR(a,cc(a))}function cc(a){var b=[],c,d,e,f,g=cb(a),h=-1,i=a.length-1;while(++h<i)c=ca(a[h],a[h+1]),Math.abs(c)<1e-6?g[h]=g[h+1]=0:(d=g[h]/c,e=g[h+1]/c,f=d*d+e*e,f>9&&(f=c*3/Math.sqrt(f),g[h]=f*d,g[h+1]=f*e));h=-1;while(++h<=i)f=(a[Math.min(i,h+1)][0]-a[Math.max(0,h-1)][0])/(6*(1+g[h]*g[h])),b.push([f||0,g[h]*f||0]);return b}function cb(a){var b=0,c=a.length-1,d=[],e=a[0],f=a[1],g=d[0]=ca(e,f);while(++b<c)d[b]=g+(g=ca(e=f,f=a[b+1]));d[b]=g;return d}function ca(a,b){return(b[1]-a[1])/(b[0]-a[0])}function b_(a,b,c){a.push(\"C\",bX(bY,b),\",\",bX(bY,c),\",\",bX(bZ,b),\",\",bX(bZ,c),\",\",bX(b$,b),\",\",bX(b$,c))}function bX(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}function bW(a,b){var c=a.length-1,d=a[0][0],e=a[0][1],f=a[c][0]-d,g=a[c][1]-e,h=-1,i,j;while(++h<=c)i=a[h],j=h/c,i[0]=b*i[0]+(1-b)*(d+j*f),i[1]=b*i[1]+(1-b)*(e+j*g);return bT(a)}function bV(a){var b,c=-1,d=a.length,e=d+4,f,g=[],h=[];while(++c<4)f=a[c%d],g.push(f[0]),h.push(f[1]);b=[bX(b$,g),\",\",bX(b$,h)],--c;while(++c<e)f=a[c%d],g.shift(),g.push(f[0]),h.shift(),h.push(f[1]),b_(b,g,h);return b.join(\"\")}function bU(a){if(a.length<4)return bL(a);var b=[],c=-1,d=a.length,e,f=[0],g=[0];while(++c<3)e=a[c],f.push(e[0]),g.push(e[1]);b.push(bX(b$,f)+\",\"+bX(b$,g)),--c;while(++c<d)e=a[c],f.shift(),f.push(e[0]),g.shift(),g.push(e[1]),b_(b,f,g);return b.join(\"\")}function bT(a){if(a.length<3)return bL(a);var b=[],c=1,d=a.length,e=a[0],f=e[0],g=e[1],h=[f,f,f,(e=a[1])[0]],i=[g,g,g,e[1]];b.push(f,\",\",g),b_(b,h,i);while(++c<d)e=a[c],h.shift(),h.push(e[0]),i.shift(),i.push(e[1]),b_(b,h,i);c=-1;while(++c<2)h.shift(),h.push(e[0]),i.shift(),i.push(e[1]),b_(b,h,i);return b.join(\"\")}function bS(a,b){var c=[],d=(1-b)/2,e,f=a[0],g=a[1],h=1,i=a.length;while(++h<i)e=f,f=g,g=a[h],c.push([d*(g[0]-e[0]),d*(g[1]-e[1])]);return c}function bR(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return bL(a);var c=a.length!=b.length,d=\"\",e=a[0],f=a[1],g=b[0],h=g,i=1;c&&(d+=\"Q\"+(f[0]-g[0]*2/3)+\",\"+(f[1]-g[1]*2/3)+\",\"+f[0]+\",\"+f[1],e=a[1],i=2);if(b.length>1){h=b[1],f=a[i],i++,d+=\"C\"+(e[0]+g[0])+\",\"+(e[1]+g[1])+\",\"+(f[0]-h[0])+\",\"+(f[1]-h[1])+\",\"+f[0]+\",\"+f[1];for(var j=2;j<b.length;j++,i++)f=a[i],h=b[j],d+=\"S\"+(f[0]-h[0])+\",\"+(f[1]-h[1])+\",\"+f[0]+\",\"+f[1]}if(c){var k=a[i];d+=\"Q\"+(f[0]+h[0]*2/3)+\",\"+(f[1]+h[1]*2/3)+\",\"+k[0]+\",\"+k[1]}return d}function bQ(a,b,c){return a.length<3?bL(a):a[0]+bR(a,bS(a,b))}function bP(a,b){return a.length<3?bL(a):a[0]+bR((a.push(a[0]),a),bS([a[a.length-2]].concat(a,[a[1]]),b))}function bO(a,b){return a.length<4?bL(a):a[1]+bR(a.slice(1,a.length-1),bS(a,b))}function bN(a){var b=[],c=0,d=a.length,e=a[0];b.push(e[0],\",\",e[1]);while(++c<d)b.push(\"H\",(e=a[c])[0],\"V\",e[1]);return b.join(\"\")}function bM(a){var b=[],c=0,d=a.length,e=a[0];b.push(e[0],\",\",e[1]);while(++c<d)b.push(\"V\",(e=a[c])[1],\"H\",e[0]);return b.join(\"\")}function bL(a){var b=[],c=0,d=a.length,e=a[0];b.push(e[0],\",\",e[1]);while(++c<d)b.push(\"L\",(e=a[c])[0],\",\",e[1]);return b.join(\"\")}function bJ(a){return a[1]}function bI(a){return a[0]}function bH(a,b,c,d){var e=[],f=-1,g=b.length,h=typeof c==\"function\",i=typeof d==\"function\",j;if(h&&i)while(++f<g)e.push([c.call(a,j=b[f],f),d.call(a,j,f)]);else if(h)while(++f<g)e.push([c.call(a,b[f],f),d]);else if(i)while(++f<g)e.push([c,d.call(a,b[f],f)]);else while(++f<g)e.push([c,d]);return e}function bG(a){function g(d){return d.length<1?null:\"M\"+e(a(bH(this,d,b,c)),f)}var b=bI,c=bJ,d=\"linear\",e=bK[d],f=.7;g.x=function(a){if(!arguments.length)return b;b=a;return g},g.y=function(a){if(!arguments.length)return c;c=a;return g},g.interpolate=function(a){if(!arguments.length)return d;e=bK[d=a];return g},g.tension=function(a){if(!arguments.length)return f;f=a;return g};return g}function bF(a){return a.endAngle}function bE(a){return a.startAngle}function bD(a){return a.outerRadius}function bC(a){return a.innerRadius}function bv(a){return function(b){return b<0?-Math.pow(-b,a):Math.pow(b,a)}}function bu(a){return a.toPrecision(1)}function bt(a){return-Math.log(-a)/Math.LN10}function bs(a){return Math.log(a)/Math.LN10}function br(a,b,c,d){var e=[],f=[],g=0,h=a.length;while(++g<h)e.push(c(a[g-1],a[g])),f.push(d(b[g-1],b[g]));return function(b){var c=d3.bisect(a,b,1,a.length-1)-1;return f[c](e[c](b))}}function bq(a,b,c,d){var e=c(a[0],a[1]),f=d(b[0],b[1]);return function(a){return f(e(a))}}function bp(a,b){return d3.format(\",.\"+Math.max(0,-Math.floor(Math.log(bn(a,b)[2])/Math.LN10+.01))+\"f\")}function bo(a,b){return d3.range.apply(d3,bn(a,b))}function bn(a,b){var c=bi(a),d=c[1]-c[0],e=Math.pow(10,Math.floor(Math.log(d/b)/Math.LN10)),f=b/d*e;f<=.15?e*=10:f<=.35?e*=5:f<=.75&&(e*=2),c[0]=Math.ceil(c[0]/e)*e,c[1]=Math.floor(c[1]/e)*e+e*.5,c[2]=e;return c}function bm(a){a=Math.pow(10,Math.round(Math.log(a)/Math.LN10)-1);return{floor:function(b){return Math.floor(b/a)*a},ceil:function(b){return Math.ceil(b/a)*a}}}function bl(a,b){a.range=d3.rebind(a,b.range),a.rangeRound=d3.rebind(a,b.rangeRound),a.interpolate=d3.rebind(a,b.interpolate),a.clamp=d3.rebind(a,b.clamp);return a}function bk(){return Math}function bj(a,b){var c=0,d=a.length-1,e=a[c],f=a[d],g;f<e&&(g=c,c=d,d=g,g=e,e=f,f=g),b=b(f-e),a[c]=b.floor(e),a[d]=b.ceil(f);return a}function bi(a){var b=a[0],c=a[a.length-1];return b<c?[b,c]:[c,b]}function bh(){}function bf(){var a=null,b=bb,c=Infinity;while(b)b.flush?b=a?a.next=b.next:bb=b.next:(c=Math.min(c,b.then+b.delay),b=(a=b).next);return c}function be(){var a,b=Date.now(),c=bb;while(c)a=b-c.then,a>=c.delay&&(c.flush=c.callback(a)),c=c.next;var d=bf()-b;d>24?(isFinite(d)&&(clearTimeout(bd),bd=setTimeout(be,d)),bc=0):(bc=1,bg(be))}function ba(a){return typeof a==\"function\"?function(b,c,d){var e=a.call(this,b,c)+\"\";return d!=e&&d3.interpolate(d,e)}:(a=a+\"\",function(b,c,d){return d!=a&&d3.interpolate(d,a)})}function _(a){function n(b){var h=!0,l=-1;a.each(function(){if(i[++l]!==2){var a=(b-j[l])/k[l],n=this.__transition__,o,p,q=e[l];if(a<1){h=!1;if(a<0)return}else a=1;if(i[l]){if(!n||n.active!==c){i[l]=2;return}}else{if(!n||n.active>c){i[l]=2;return}i[l]=1,g.start.dispatch.apply(this,arguments),q=e[l]={},n.active=c;for(p in d)if(o=d[p].apply(this,arguments))q[p]=o}o=m(a);for(p in q)q[p].call(this,o);if(a===1){i[l]=2;if(n.active===c){var r=n.owner;r===c&&(delete this.__transition__,f&&this.parentNode&&this.parentNode.removeChild(this)),$=c,g.end.dispatch.apply(this,arguments),$=0,n.owner=r}}}});return h}var b={},c=$||++Z,d={},e=[],f=!1,g=d3.dispatch(\"start\",\"end\"),i=[],j=[],k=[],l,m=d3.ease(\"cubic-in-out\");a.each(function(){(this.__transition__||(this.__transition__={})).owner=c}),b.delay=function(c){var d=Infinity,e=-1;typeof c==\"function\"?a.each(function(a,b){var f=j[++e]=+c.apply(this,arguments);f<d&&(d=f)}):(d=+c,a.each(function(a,b){j[++e]=d})),d3.timer(n,d);return b},b.duration=function(c){var d=-1;typeof c==\"function\"?(l=0,a.each(function(a,b){var e=k[++d]=+c.apply(this,arguments);e>l&&(l=e)})):(l=+c,a.each(function(a,b){k[++d]=l}));return b},b.ease=function(a){m=typeof a==\"function\"?a:d3.ease.apply(d3,arguments);return b},b.attrTween=function(a,c){function f(b,d){var e=c.call(this,b,d,this.getAttributeNS(a.space,a.local));return e&&function(b){this.setAttributeNS(a.space,a.local,e(b))}}function e(b,d){var e=c.call(this,b,d,this.getAttribute(a));return e&&function(b){this.setAttribute(a,e(b))}}d[\"attr.\"+a]=a.local?f:e;return b},b.attr=function(a,c){return b.attrTween(a,ba(c))},b.styleTween=function(a,c,e){function f(b,d){var f=c.call(this,b,d,window.getComputedStyle(this,null).getPropertyValue(a));return f&&function(b){this.style.setProperty(a,f(b),e)}}arguments.length<3&&(e=null),d[\"style.\"+a]=f;return b},b.style=function(a,c,d){arguments.length<3&&(d=null);return b.styleTween(a,ba(c),d)},b.text=function(a){d.text=function(b,c){this.textContent=typeof a==\"function\"?a.call(this,b,c):a};return b},b.select=function(b){var c,d=_(a.select(b)).ease(m);c=-1,d.delay(function(a,b){return j[++c]}),c=-1,d.duration(function(a,b){return k[++c]});return d},b.selectAll=function(b){var c,d=_(a.selectAll(b)).ease(m);c=-1,d.delay(function(a,b){return j[b?c:++c]}),c=-1,d.duration(function(a,b){return k[b?c:++c]});return d},b.remove=function(){f=!0;return b},b.each=function(a,c){g[a].add(c);return b},b.call=h;return b.delay(0).duration(250)}function Y(a){return{__data__:a}}function X(a){arguments.length||(a=d3.ascending);return function(b,c){return a(b&&b.__data__,c&&c.__data__)}}function W(a){function b(b){var c=[],d,e,f,g;for(var h=0,i=a.length;h<i;h++){f=a[h],c.push(d=[]),d.parentNode=f.parentNode;for(var j=0,k=f.length;j<k;j++)(g=f[j])?(d.push(e=b(f.parentNode)),e.__data__=g.__data__):d.push(null)}return V(c)}a.append=function(a){function d(b){return b.appendChild(document.createElementNS(a.space,a.local))}function c(b){return b.appendChild(document.createElement(a))}a=d3.ns.qualify(a);return b(a.local?d:c)},a.insert=function(a,c){function e(b){return b.insertBefore(document.createElementNS(a.space,a.local),S(c,b))}function d(b){return b.insertBefore(document.createElement(a),S(c,b))}a=d3.ns.qualify(a);return b(a.local?e:d)};return a}function V(a){function d(b){for(var c=0,d=a.length;c<d;c++){var e=a[c];for(var f=0,g=e.length;f<g;f++){var h=e[f];if(h)return b.call(h,h.__data__,f)}}return null}function c(b){var c=[],d,e,f;for(var g=0,h=a.length;g<h;g++){e=a[g];for(var i=0,j=e.length;i<j;i++)if(f=e[i])c.push(d=b(f)),d.parentNode=f}return V(c)}function b(b){var c=[],d,e,f,g;for(var h=0,i=a.length;h<i;h++){f=a[h],c.push(d=[]),d.parentNode=f.parentNode;for(var j=0,k=f.length;j<k;j++)(g=f[j])?(d.push(e=b(g)),e&&\"__data__\"in g&&(e.__data__=g.__data__)):d.push(null)}return V(c)}a.select=function(a){return b(function(b){return S(a,b)})},a.selectAll=function(a){return c(function(b){return T(a,b)})},a.filter=function(b){var c=[],d,e,f;for(var g=0,h=a.length;g<h;g++){e=a[g],c.push(d=[]),d.parentNode=e.parentNode;for(var i=0,j=e.length;i<j;i++)(f=e[i])&&b.call(f,f.__data__,i)&&d.push(f)}return V(c)},a.map=function(b){var c,d;for(var e=0,f=a.length;e<f;e++){c=a[e];for(var g=0,h=c.length;g<h;g++)if(d=c[g])d.__data__=b.call(d,d.__data__,g)}return a},a.data=function(b,c){function g(a,b){var g=0,h=a.length,i=b.length,j=Math.min(h,i),k=Math.max(h,i),l=[],m=[],n=[],o,p;if(c){var q={},r=[],s,t=b.length;for(g=0;g<h;g++)s=c.call(o=a[g],o.__data__,g),s in q?n[t++]=o:q[s]=o,r.push(s);for(g=0;g<i;g++)o=q[s=c.call(b,p=b[g],g)],o?(o.__data__=p,l[g]=o,m[g]=n[g]=null):(m[g]=Y(p),l[g]=n[g]=null),delete q[s];for(g=0;g<h;g++)r[g]in q&&(n[g]=a[g])}else{for(;g<j;g++)o=a[g],p=b[g],o?(o.__data__=p,l[g]=o,m[g]=n[g]=null):(m[g]=Y(p),l[g]=n[g]=null);for(;g<i;g++)m[g]=Y(b[g]),l[g]=n[g]=null;for(;g<k;g++)n[g]=a[g],m[g]=l[g]=null}m.parentNode=l.parentNode=n.parentNode=a.parentNode,d.push(m),e.push(l),f.push(n)}var d=[],e=[],f=[],h=-1,i=a.length,j;if(typeof b==\"function\")while(++h<i)g(j=a[h],b.call(j,j.parentNode.__data__,h));else while(++h<i)g(j=a[h],b);var k=V(e);k.enter=function(){return W(d)},k.exit=function(){return V(f)};return k},a.each=function(b){for(var c=0,d=a.length;c<d;c++){var e=a[c];for(var f=0,g=e.length;f<g;f++){var h=e[f];h&&b.call(h,h.__data__,f)}}return a},a.empty=function(){return!d(function(){return!0})},a.node=function(){return d(function(){return this})},a.attr=function(b,c){function j(){var a=c.apply(this,arguments);a==null?this.removeAttributeNS(b.space,b.local):this.setAttributeNS(b.space,b.local,a)}function i(){var a=c.apply(this,arguments);a==null?this.removeAttribute(b):this.setAttribute(b,a)}function h(){this.setAttributeNS(b.space,b.local,c)}function g(){this.setAttribute(b,c)}function f(){this.removeAttributeNS(b.space,b.local)}function e(){this.removeAttribute(b)}b=d3.ns.qualify(b);return arguments.length<2?d(b.local?function(){return this.getAttributeNS(b.space,b.local)}:function(){return this.getAttribute(b)}):a.each(c==null?b.local?f:e:typeof c==\"function\"?b.local?j:i:b.local?h:g)},a.classed=function(b,c){function i(){(c.apply(this,arguments)?f:h).call(this)}function h(){if(a=this.classList)return a.remove(b);var a=this.className,c=a.baseVal!=null,d=c?a.baseVal:a;d=g(d.replace(e,\" \")),c?a.baseVal=d:this.className=d}function f(){if(a=this.classList)return a.add(b);var a=this.className,c=a.baseVal!=null,d=c?a.baseVal:a;e.lastIndex=0,e.test(d)||(d=g(d+\" \"+b),c?a.baseVal=d:this.className=d)}var e=new RegExp(\"(^|\\\\s+)\"+d3.requote(b)+\"(\\\\s+|$)\",\"g\");return arguments.length<2?d(function(){if(a=this.classList)return a.contains(b);var a=this.className;e.lastIndex=0;return e.test(a.baseVal!=null?a.baseVal:a)}):a.each(typeof c==\"function\"?i:c?f:h)},a.style=function(b,c,e){function h(){var a=c.apply(this,arguments);a==null?this.style.removeProperty(b):this.style.setProperty(b,a,e)}function g(){this.style.setProperty(b,c,e)}function f(){this.style.removeProperty(b)}arguments.length<3&&(e=\"\");return arguments.length<2?d(function(){return window.getComputedStyle(this,null).getPropertyValue(b)}):a.each(c==null?f:typeof c==\"function\"?h:g)},a.property=function(b,c){function g(){var a=c.apply(this,arguments);a==null?delete this[b]:this[b]=a}function f(){this[b]=c}function e(){delete this[b]}b=d3.ns.qualify(b);return arguments.length<2?d(function(){return this[b]}):a.each(c==null?e:typeof c==\"function\"?g:f)},a.text=function(b){function e(){this.textContent=b.apply(this,arguments)}function c(){this.textContent=b}return arguments.length<1?d(function(){return this.textContent}):a.each(typeof b==\"function\"?e:c)},a.html=function(b){function e(){this.innerHTML=b.apply(this,arguments)}function c(){this.innerHTML=b}return arguments.length<1?d(function(){return this.innerHTML}):a.each(typeof b==\"function\"?e:c)},a.append=function(a){function d(b){return b.appendChild(document.createElementNS(a.space,a.local))}function c(b){return b.appendChild(document.createElement(a))}a=d3.ns.qualify(a);return b(a.local?d:c)},a.insert=function(a,c){function e(b){return b.insertBefore(document.createElementNS(a.space,a.local),S(c,b))}function d(b){return b.insertBefore(document.createElement(a),S(c,b))}a=d3.ns.qualify(a);return b(a.local?e:d)},a.remove=function(){return a.each(function(){var a=this.parentNode;a&&a.removeChild(this)})},a.sort=function(b){b=X.apply(this,arguments);for(var c=0,d=a.length;c<d;c++){var e=a[c];e.sort(b);for(var f=1,g=e.length,h=e[0];f<g;f++){var i=e[f];i&&(h&&h.parentNode.insertBefore(i,h.nextSibling),h=i)}}return a},a.on=function(b,c,d){arguments.length<3&&(d=!1);var e=b.indexOf(\".\"),f=e===-1?b:b.substring(0,e),g=\"__on\"+b;return a.each(function(a,b){function h(a){var d=d3.event;d3.event=a;try{c.call(this,e.__data__,b)}finally{d3.event=d}}this[g]&&this.removeEventListener(f,this[g],d),c&&this.addEventListener(f,this[g]=h,d);var e=this})},a.transition=function(){return _(a)},a.call=h;return a}function R(a,b,c){function g(a){return Math.round(f(a)*255)}function f(a){a>360?a-=360:a<0&&(a+=360);return a<60?d+(e-d)*a/60:a<180?e:a<240?d+(e-d)*(240-a)/60:d}var d,e;a=a%360,a<0&&(a+=360),b=b<0?0:b>1?1:b,c=c<0?0:c>1?1:c,e=c<=.5?c*(1+b):c+b-c*b,d=2*c-e;return H(g(a+120),g(a),g(a-120))}function Q(a,b,c){this.h=a,this.s=b,this.l=c}function P(a,b,c){return new Q(a,b,c)}function M(a){var b=parseFloat(a);return a.charAt(a.length-1)===\"%\"?Math.round(b*2.55):b}function L(a,b,c){var d=Math.min(a/=255,b/=255,c/=255),e=Math.max(a,b,c),f=e-d,g,h,i=(e+d)/2;f?(h=i<.5?f/(e+d):f/(2-e-d),a==e?g=(b-c)/f+(b<c?6:0):b==e?g=(c-a)/f+2:g=(a-b)/f+4,g*=60):h=g=0;return P(g,h,i)}function K(a,b,c){var d=0,e=0,f=0,g,h,i;g=/([a-z]+)\\((.*)\\)/i.exec(a);if(g){h=g[2].split(\",\");switch(g[1]){case\"hsl\":return c(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case\"rgb\":return b(M(h[0]),M(h[1]),M(h[2]))}}if(i=N[a])return b(i.r,i.g,i.b);a!=null&&a.charAt(0)===\"#\"&&(a.length===4?(d=a.charAt(1),d+=d,e=a.charAt(2),e+=e,f=a.charAt(3),f+=f):a.length===7&&(d=a.substring(1,3),e=a.substring(3,5),f=a.substring(5,7)),d=parseInt(d,16),e=parseInt(e,16),f=parseInt(f,16));return b(d,e,f)}function J(a){return a<16?\"0\"+a.toString(16):a.toString(16)}function I(a,b,c){this.r=a,this.g=b,this.b=c}function H(a,b,c){return new I(a,b,c)}function G(a,b){b=1/(b-(a=+a));return function(c){return Math.max(0,Math.min(1,(c-a)*b))}}function F(a,b){b=1/(b-(a=+a));return function(c){return(c-a)*b}}function E(a){return a in D||/\\bcolor\\b/.test(a)?d3.interpolateRgb:d3.interpolate}function B(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375}function A(a){a||(a=1.70158);return function(b){return b*b*((a+1)*b-a)}}function z(a,b){var c;arguments.length<2&&(b=.45),arguments.length<1?(a=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/a);return function(d){return 1+a*Math.pow(2,10*-d)*Math.sin((d-c)*2*Math.PI/b)}}function y(a){return 1-Math.sqrt(1-a*a)}function x(a){return Math.pow(2,10*(a-1))}function w(a){return 1-Math.cos(a*Math.PI/2)}function v(a){return function(b){return Math.pow(b,a)}}function u(a){return a}function t(a){return function(b){return.5*(b<.5?a(2*b):2-a(2-2*b))}}function s(a){return function(b){return 1-a(1-b)}}function n(a){var b=a.lastIndexOf(\".\"),c=b>=0?a.substring(b):(b=a.length,\"\"),d=[];while(b>0)d.push(a.substring(b-=3,b+3));return d.reverse().join(\",\")+c}function m(a){return a+\"\"}function j(a){var b={},c=[];b.add=function(a){for(var d=0;d<c.length;d++)if(c[d].listener==a)return b;c.push({listener:a,on:!0});return b},b.remove=function(a){for(var d=0;d<c.length;d++){var e=c[d];if(e.listener==a){e.on=!1,c=c.slice(0,d).concat(c.slice(d+1));break}}return b},b.dispatch=function(){var a=c;for(var b=0,d=a.length;b<d;b++){var e=a[b];e.on&&e.listener.apply(this,arguments)}};return b}function h(a){a.apply(this,(arguments[0]=this,arguments));return this}function g(a){return a.replace(/(^\\s+)|(\\s+$)/g,\"\").replace(/\\s+/g,\" \")}function f(a){return a==null}function e(a){return a.length}function c(a){return Array.prototype.slice.call(a)}function b(a){var b=-1,c=a.length,d=[];while(++b<c)d.push(a[b]);return d}d3={version:\"1.29.7\"},Date.now||(Date.now=function(){return+(new Date)}),Object.create||(Object.create=function(a){function b(){}b.prototype=a;return new b});var a=c;try{a(document.documentElement.childNodes)[0].nodeType}catch(d){a=b}d3.functor=function(a){return typeof a==\"function\"?a:function(){return a}},d3.rebind=function(a,b){return function(){var c=b.apply(a,arguments);return arguments.length?a:c}},d3.ascending=function(a,b){return a<b?-1:a>b?1:a>=b?0:NaN},d3.descending=function(a,b){return b<a?-1:b>a?1:b>=a?0:NaN},d3.min=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++c<d&&((e=a[c])==null||e!=e))e=undefined;while(++c<d)(f=a[c])!=null&&e>f&&(e=f)}else{while(++c<d&&((e=b.call(a,a[c],c))==null||e!=e))e=undefined;while(++c<d)(f=b.call(a,a[c],c))!=null&&e>f&&(e=f)}return e},d3.max=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++c<d&&((e=a[c])==null||e!=e))e=undefined;while(++c<d)(f=a[c])!=null&&f>e&&(e=f)}else{while(++c<d&&((e=b.call(a,a[c],c))==null||e!=e))e=undefined;while(++c<d)(f=b.call(a,a[c],c))!=null&&f>e&&(e=f)}return e},d3.sum=function(a,b){var c=0,d=a.length,e,f=-1;if(arguments.length===1)while(++f<d)isNaN(e=+a[f])||(c+=e);else while(++f<d)isNaN(e=+b.call(a,a[f],f))||(c+=e);return c},d3.quantile=function(a,b){var c=(a.length-1)*b+1,d=Math.floor(c),e=a[d-1],f=c-d;return f?e+f*(a[d]-e):e},d3.zip=function(){if(!(f=arguments.length))return[];for(var a=-1,b=d3.min(arguments,e),c=Array(b);++a<b;)for(var d=-1,f,g=c[a]=Array(f);++d<f;)g[d]=arguments[d][a];return c},d3.bisectLeft=function(a,b,c,d){arguments.length<3&&(c=0),arguments.length<4&&(d=a.length);while(c<d){var e=c+d>>1;a[e]<b?c=e+1:d=e}return c},d3.bisect=d3.bisectRight=function(a,b,c,d){arguments.length<3&&(c=0),arguments.length<4&&(d=a.length);while(c<d){var e=c+d>>1;b<a[e]?d=e:c=e+1}return c},d3.first=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c<d)b.call(a,e,f=a[c])>0&&(e=f);return e},d3.last=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c<d)b.call(a,e,f=a[c])<=0&&(e=f);return e},d3.nest=function(){function g(a,d){if(d>=b.length)return a;var e=[],f=c[d++],h;for(h in a)e.push({key:h,values:g(a[h],d)});f&&e.sort(function(a,b){return f(a.key,b.key)});return e}function f(c,g){if(g>=b.length)return e?e.call(a,c):d?c.sort(d):c;var h=-1,i=c.length,j=b[g++],k,l,m={};while(++h<i)(k=j(l=c[h]))in m?m[k].push(l):m[k]=[l];for(k in m)m[k]=f(m[k],g);return m}var a={},b=[],c=[],d,e;a.map=function(a){return f(a,0)},a.entries=function(a){return g(f(a,0),0)},a.key=function(c){b.push(c);return a},a.sortKeys=function(d){c[b.length-1]=d;return a},a.sortValues=function(b){d=b;return a},a.rollup=function(b){e=b;return a};return a},d3.keys=function(a){var b=[];for(var c in a)b.push(c);return b},d3.values=function(a){var b=[];for(var c in a)b.push(a[c]);return b},d3.entries=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},d3.permute=function(a,b){var c=[],d=-1,e=b.length;while(++d<e)c[d]=a[b[d]];return c},d3.merge=function(a){return Array.prototype.concat.apply([],a)},d3.split=function(a,b){var c=[],d=[],e,g=-1,h=a.length;arguments.length<2&&(b=f);while(++g<h)b.call(d,e=a[g],g)?d=[]:(d.length||c.push(d),d.push(e));return c},d3.range=function(a,b,c){arguments.length<3&&(c=1,arguments.length<2&&(b=a,a=0));if((b-a)/c==Infinity)throw new Error(\"infinite range\");var d=[],e=-1,f;if(c<0)while((f=a+c*++e)>b)d.push(f);else while((f=a+c*++e)<b)d.push(f);return d},d3.requote=function(a){return a.replace(i,\"\\\\$&\")};var i=/[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;d3.round=function(a,b){return b?Math.round(a*Math.pow(10,b))*Math.pow(10,-b):Math.round(a)},d3.xhr=function(a,b,c){var d=new XMLHttpRequest;arguments.length<3?c=b:b&&d.overrideMimeType&&d.overrideMimeType(b),d.open(\"GET\",a,!0),d.onreadystatechange=function(){d.readyState===4&&c(d.status<300?d:null)},d.send(null)},d3.text=function(a,b,c){function d(a){c(a&&a.responseText)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)},d3.json=function(a,b){d3.text(a,\"application/json\",function(a){b(a?JSON.parse(a):null)})},d3.html=function(a,b){d3.text(a,\"text/html\",function(a){if(a!=null){var c=document.createRange();c.selectNode(document.body),a=c.createContextualFragment(a)}b(a)})},d3.xml=function(a,b,c){function d(a){c(a&&a.responseXML)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)},d3.ns={prefix:{svg:\"http://www.w3.org/2000/svg\",xhtml:\"http://www.w3.org/1999/xhtml\",xlink:\"http://www.w3.org/1999/xlink\",xml:\"http://www.w3.org/XML/1998/namespace\",xmlns:\"http://www.w3.org/2000/xmlns/\"},qualify:function(a){var b=a.indexOf(\":\");return b<0?a:{space:d3.ns.prefix[a.substring(0,b)],local:a.substring(b+1)}}},d3.dispatch=function(a){var b={},c;for(var d=0,e=arguments.length;d<e;d++)c=arguments[d],b[c]=j(c);return b},d3.format=function(a){var b=k.exec(a),c=b[1]||\" \",d=b[3]||\"\",e=b[5],f=+b[6],g=b[7],h=b[8],i=b[9],j=!1,o=!1;h&&(h=h.substring(1)),e&&(c=\"0\",g&&(f-=Math.floor((f-1)/4)));switch(i){case\"n\":g=!0,i=\"g\";break;case\"%\":j=!0,i=\"f\";break;case\"p\":j=!0,i=\"r\";break;case\"d\":o=!0,h=\"0\"}i=l[i]||m;return function(a){var b=j?a*100:+a,k=b<0&&(b=-b)?\"−\":d;if(o&&b%1)return\"\";a=i(b,h);if(e){var l=a.length+k.length;l<f&&(a=Array(f-l+1).join(c)+a),g&&(a=n(a)),a=k+a}else{g&&(a=n(a)),a=k+a;var l=a.length;l<f&&(a=Array(f-l+1).join(c)+a)}j&&(a+=\"%\");return a}};var k=/(?:([^{])?([<>=^]))?([+\\- ])?(#)?(0)?([0-9]+)?(,)?(\\.[0-9]+)?([a-zA-Z%])?/,l={g:function(a,b){return a.toPrecision(b)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},r:function(a,b){var c=1+Math.floor(1e-15+Math.log(a)/Math.LN10);return d3.round(a,b-c).toFixed(Math.max(0,Math.min(20,b-c)))}},o=v(2),p=v(3),q={linear:function(){return u},poly:v,quad:function(){return o},cubic:function(){return p},sin:function(){return w},exp:function(){return x},circle:function(){return y},elastic:z,back:A,bounce:function(){return B}},r={\"in\":function(a){return a},out:s,\"in-out\":t,\"out-in\":function(a){return t(s(a))}};d3.ease=function(a){var b=a.indexOf(\"-\"),c=b>=0?a.substring(0,b):a,d=b>=0?a.substring(b+1):\"in\";return r[d](q[c].apply(null,Array.prototype.slice.call(arguments,1)))},d3.event=null,d3.interpolate=function(a,b){var c=d3.interpolators.length,d;while(--c>=0&&!(d=d3.interpolators[c](a,b)));return d},d3.interpolateNumber=function(a,b){b-=a;return function(c){return a+b*c}},d3.interpolateRound=function(a,b){b-=a;return function(c){return Math.round(a+b*c)}},d3.interpolateString=function(a,b){var c,d,e,f=0,g=0,h=[],i=[],j,k;C.lastIndex=0;for(d=0;c=C.exec(b);++d)c.index&&h.push(b.substring(f,g=c.index)),i.push({i:h.length,x:c[0]}),h.push(null),f=C.lastIndex;f<b.length&&h.push(b.substring(f));for(d=0,j=i.length;(c=C.exec(a))&&d<j;++d){k=i[d];if(k.x==c[0]){if(k.i)if(h[k.i+1]==null){h[k.i-1]+=k.x,h.splice(k.i,1);for(e=d+1;e<j;++e)i[e].i--}else{h[k.i-1]+=k.x+h[k.i+1],h.splice(k.i,2);for(e=d+1;e<j;++e)i[e].i-=2}else if(h[k.i+1]==null)h[k.i]=k.x;else{h[k.i]=k.x+h[k.i+1],h.splice(k.i+1,1);for(e=d+1;e<j;++e)i[e].i--}i.splice(d,1),j--,d--}else k.x=d3.interpolateNumber(parseFloat(c[0]),parseFloat(k.x))}while(d<j)k=i.pop(),h[k.i+1]==null?h[k.i]=k.x:(h[k.i]=k.x+h[k.i+1],h.splice(k.i+1,1)),j--;return h.length===1?h[0]==null?i[0].x:function(){return b}:function(a){for(d=0;d<j;++d)h[(k=i[d]).i]=k.x(a);return h.join(\"\")}},d3.interpolateRgb=function(a,b){a=d3.rgb(a),b=d3.rgb(b);var c=a.r,d=a.g,e=a.b,f=b.r-c,g=b.g-d,h=b.b-e;return function(a){return\"rgb(\"+Math.round(c+f*a)+\",\"+Math.round(d+g*a)+\",\"+Math.round(e+h*a)+\")\"}},d3.interpolateHsl=function(a,b){a=d3.hsl(a),b=d3.hsl(b);var c=a.h,d=a.s,e=a.l,f=b.h-c,g=b.s-d,h=b.l-e;return function(a){return R(c+f*a,d+g*a,e+h*a).toString()}},d3.interpolateArray=function(a,b){var c=[],d=[],e=a.length,f=b.length,g=Math.min(a.length,b.length),h;for(h=0;h<g;++h)c.push(d3.interpolate(a[h],b[h]));for(;h<e;++h)d[h]=a[h];for(;h<f;++h)d[h]=b[h];return function(a){for(h=0;h<g;++h)d[h]=c[h](a);return d}},d3.interpolateObject=function(a,b){var c={},d={},e;for(e in a)e in b?c[e]=E(e)(a[e],b[e]):d[e]=a[e];for(e in b)e in a||(d[e]=b[e]);return function(a){for(e in c)d[e]=c[e](a);return d}};var C=/[-+]?(?:\\d+\\.\\d+|\\d+\\.|\\.\\d+|\\d+)(?:[eE][-]?\\d+)?/g,D={background:1,fill:1,stroke:1};d3.interpolators=[d3.interpolateObject,function(a,b){return b instanceof Array&&d3.interpolateArray(a,b)},function(a,b){return typeof b==\"string\"&&d3.interpolateString(String(a),b)},function(a,b){return(typeof b==\"string\"?b in N||/^(#|rgb\\(|hsl\\()/.test(b):b instanceof I||b instanceof Q)&&d3.interpolateRgb(String(a),b)},function(a,b){return typeof b==\"number\"&&d3.interpolateNumber(+a,b)}],d3.rgb=function(a,b,c){return arguments.length===1?K(\"\"+a,H,R):H(~~a,~~b,~~c)},I.prototype.brighter=function(a){a=Math.pow(.7,arguments.length?a:1);var b=this.r,c=this.g,d=this.b,e=30;if(!b&&!c&&!d)return H(e,e,e);b&&b<e&&(b=e),c&&c<e&&(c=e),d&&d<e&&(d=e);return H(Math.min(255,Math.floor(b/a)),Math.min(255,Math.floor(c/a)),Math.min(255,Math.floor(d/a)))},I.prototype.darker=function(a){a=Math.pow(.7,arguments.length?a:1);return H(Math.max(0,Math.floor(a*this.r)),Math.max(0,Math.floor(a*this.g)),Math.max(0,Math.floor(a*this.b)))},I.prototype.hsl=function(){return L(this.r,this.g,this.b)},I.prototype.toString=function(){return\"#\"+J(this.r)+J(this.g)+J(this.b)};var N={aliceblue:\"#f0f8ff\",antiquewhite:\"#faebd7\",aqua:\"#00ffff\",aquamarine:\"#7fffd4\",azure:\"#f0ffff\",beige:\"#f5f5dc\",bisque:\"#ffe4c4\",black:\"#000000\",blanchedalmond:\"#ffebcd\",blue:\"#0000ff\",blueviolet:\"#8a2be2\",brown:\"#a52a2a\",burlywood:\"#deb887\",cadetblue:\"#5f9ea0\",chartreuse:\"#7fff00\",chocolate:\"#d2691e\",coral:\"#ff7f50\",cornflowerblue:\"#6495ed\",cornsilk:\"#fff8dc\",crimson:\"#dc143c\",cyan:\"#00ffff\",darkblue:\"#00008b\",darkcyan:\"#008b8b\",darkgoldenrod:\"#b8860b\",darkgray:\"#a9a9a9\",darkgreen:\"#006400\",darkgrey:\"#a9a9a9\",darkkhaki:\"#bdb76b\",darkmagenta:\"#8b008b\",darkolivegreen:\"#556b2f\",darkorange:\"#ff8c00\",darkorchid:\"#9932cc\",darkred:\"#8b0000\",darksalmon:\"#e9967a\",darkseagreen:\"#8fbc8f\",darkslateblue:\"#483d8b\",darkslategray:\"#2f4f4f\",darkslategrey:\"#2f4f4f\",darkturquoise:\"#00ced1\",darkviolet:\"#9400d3\",deeppink:\"#ff1493\",deepskyblue:\"#00bfff\",dimgray:\"#696969\",dimgrey:\"#696969\",dodgerblue:\"#1e90ff\",firebrick:\"#b22222\",floralwhite:\"#fffaf0\",forestgreen:\"#228b22\",fuchsia:\"#ff00ff\",gainsboro:\"#dcdcdc\",ghostwhite:\"#f8f8ff\",gold:\"#ffd700\",goldenrod:\"#daa520\",gray:\"#808080\",green:\"#008000\",greenyellow:\"#adff2f\",grey:\"#808080\",honeydew:\"#f0fff0\",hotpink:\"#ff69b4\",indianred:\"#cd5c5c\",indigo:\"#4b0082\",ivory:\"#fffff0\",khaki:\"#f0e68c\",lavender:\"#e6e6fa\",lavenderblush:\"#fff0f5\",lawngreen:\"#7cfc00\",lemonchiffon:\"#fffacd\",lightblue:\"#add8e6\",lightcoral:\"#f08080\",lightcyan:\"#e0ffff\",lightgoldenrodyellow:\"#fafad2\",lightgray:\"#d3d3d3\",lightgreen:\"#90ee90\",lightgrey:\"#d3d3d3\",lightpink:\"#ffb6c1\",lightsalmon:\"#ffa07a\",lightseagreen:\"#20b2aa\",lightskyblue:\"#87cefa\",lightslategray:\"#778899\",lightslategrey:\"#778899\",lightsteelblue:\"#b0c4de\",lightyellow:\"#ffffe0\",lime:\"#00ff00\",limegreen:\"#32cd32\",linen:\"#faf0e6\",magenta:\"#ff00ff\",maroon:\"#800000\",mediumaquamarine:\"#66cdaa\",mediumblue:\"#0000cd\",mediumorchid:\"#ba55d3\",mediumpurple:\"#9370db\",mediumseagreen:\"#3cb371\",mediumslateblue:\"#7b68ee\",mediumspringgreen:\"#00fa9a\",mediumturquoise:\"#48d1cc\",mediumvioletred:\"#c71585\",midnightblue:\"#191970\",mintcream:\"#f5fffa\",mistyrose:\"#ffe4e1\",moccasin:\"#ffe4b5\",navajowhite:\"#ffdead\",navy:\"#000080\",oldlace:\"#fdf5e6\",olive:\"#808000\",olivedrab:\"#6b8e23\",orange:\"#ffa500\",orangered:\"#ff4500\",orchid:\"#da70d6\",palegoldenrod:\"#eee8aa\",palegreen:\"#98fb98\",paleturquoise:\"#afeeee\",palevioletred:\"#db7093\",papayawhip:\"#ffefd5\",peachpuff:\"#ffdab9\",peru:\"#cd853f\",pink:\"#ffc0cb\",plum:\"#dda0dd\",powderblue:\"#b0e0e6\",purple:\"#800080\",red:\"#ff0000\",rosybrown:\"#bc8f8f\",royalblue:\"#4169e1\",saddlebrown:\"#8b4513\",salmon:\"#fa8072\",sandybrown:\"#f4a460\",seagreen:\"#2e8b57\",seashell:\"#fff5ee\",sienna:\"#a0522d\",silver:\"#c0c0c0\",skyblue:\"#87ceeb\",slateblue:\"#6a5acd\",slategray:\"#708090\",slategrey:\"#708090\",snow:\"#fffafa\",springgreen:\"#00ff7f\",steelblue:\"#4682b4\",tan:\"#d2b48c\",teal:\"#008080\",thistle:\"#d8bfd8\",tomato:\"#ff6347\",turquoise:\"#40e0d0\",violet:\"#ee82ee\",wheat:\"#f5deb3\",white:\"#ffffff\",whitesmoke:\"#f5f5f5\",yellow:\"#ffff00\",yellowgreen:\"#9acd32\"};for(var O in N)N[O]=K(N[O],H,R);d3.hsl=function(a,b,c){return arguments.length===1?K(\"\"+a,L,P):P(+a,+b,+c)},Q.prototype.brighter=function(a){a=Math.pow(.7,arguments.length?a:1);return P(this.h,this.s,this.l/a)},Q.prototype.darker=function(a){a=Math.pow(.7,arguments.length?a:1);return P(this.h,this.s,a*this.l)},Q.prototype.rgb=function(){return R(this.h,this.s,this.l)},Q.prototype.toString=function(){return\"hsl(\"+this.h+\",\"+this.s*100+\"%,\"+this.l*100+\"%)\"};var S=function(a,b){return b.querySelector(a)},T=function(b,c){return a(c.querySelectorAll(b))};typeof Sizzle==\"function\"&&(S=function(a,b){return Sizzle(a,b)[0]},T=function(a,b){return Sizzle.uniqueSort(Sizzle(a,b))});var U=V([[document]]);U[0].parentNode=document.documentElement,d3.select=function(a){return typeof a==\"string\"?U.select(a):V([[a]])},d3.selectAll=function(b){return typeof b==\"string\"?U.selectAll(b):V([a(b)])},d3.transition=U.transition;var Z=0,$=0\n",
       ",bb=null,bc,bd;d3.timer=function(a,b){var c=Date.now(),d=!1,e,f=bb;if(arguments.length<2)b=0;else if(!isFinite(b))return;while(f){if(f.callback===a){f.then=c,f.delay=b,d=!0;break}e=f,f=f.next}d||(bb={callback:a,then:c,delay:b,next:bb}),bc||(bd=clearTimeout(bd),bc=1,bg(be))},d3.timer.flush=function(){var a,b=Date.now(),c=bb;while(c)a=b-c.then,c.delay||(c.flush=c.callback(a)),c=c.next;bf()};var bg=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,17)};d3.scale={},d3.scale.linear=function(){function h(a){return e(a)}function g(){var g=a.length==2?bq:br,i=d?G:F;e=g(a,b,i,c),f=g(b,a,i,d3.interpolate);return h}var a=[0,1],b=[0,1],c=d3.interpolate,d=!1,e,f;h.invert=function(a){return f(a)},h.domain=function(b){if(!arguments.length)return a;a=b.map(Number);return g()},h.range=function(a){if(!arguments.length)return b;b=a;return g()},h.rangeRound=function(a){return h.range(a).interpolate(d3.interpolateRound)},h.clamp=function(a){if(!arguments.length)return d;d=a;return g()},h.interpolate=function(a){if(!arguments.length)return c;c=a;return g()},h.ticks=function(b){return bo(a,b)},h.tickFormat=function(b){return bp(a,b)},h.nice=function(){bj(a,bm);return g()};return g()},d3.scale.log=function(){function d(c){return a(b(c))}var a=d3.scale.linear(),b=bs,c=b.pow;d.invert=function(b){return c(a.invert(b))},d.domain=function(e){if(!arguments.length)return a.domain().map(c);b=e[0]<0?bt:bs,c=b.pow,a.domain(e.map(b));return d},d.nice=function(){a.domain(bj(a.domain(),bk));return d},d.ticks=function(){var d=bi(a.domain()),e=[];if(d.every(isFinite)){var f=Math.floor(d[0]),g=Math.ceil(d[1]),h=c(d[0]),i=c(d[1]);if(b===bt){e.push(c(f));for(;f++<g;)for(var j=9;j>0;j--)e.push(c(f)*j)}else{for(;f<g;f++)for(var j=1;j<10;j++)e.push(c(f)*j);e.push(c(f))}for(f=0;e[f]<h;f++);for(g=e.length;e[g-1]>i;g--);e=e.slice(f,g)}return e},d.tickFormat=function(){return bu};return bl(d,a)},bs.pow=function(a){return Math.pow(10,a)},bt.pow=function(a){return-Math.pow(10,-a)},d3.scale.pow=function(){function e(b){return a(c(b))}var a=d3.scale.linear(),b=1,c=Number,d=c;e.invert=function(b){return d(a.invert(b))},e.domain=function(f){if(!arguments.length)return a.domain().map(d);c=bv(b),d=bv(1/b),a.domain(f.map(c));return e},e.ticks=function(a){return bo(e.domain(),a)},e.tickFormat=function(a){return bp(e.domain(),a)},e.nice=function(){return e.domain(bj(e.domain(),bm))},e.exponent=function(a){if(!arguments.length)return b;var c=e.domain();b=a;return e.domain(c)};return bl(e,a)},d3.scale.sqrt=function(){return d3.scale.pow().exponent(.5)},d3.scale.ordinal=function(){function f(d){var e=d in b?b[d]:b[d]=a.push(d)-1;return c[e%c.length]}var a=[],b={},c=[],d=0,e=bh;f.domain=function(c){if(!arguments.length)return a;a=c,b={};var d=-1,g=-1,h=a.length;while(++d<h)c=a[d],c in b||(b[c]=++g);e();return f},f.range=function(a){if(!arguments.length)return c;c=a,e=bh;return f},f.rangePoints=function(b,g){arguments.length<2&&(g=0),(e=function(){var e=b[0],f=b[1],h=(f-e)/(a.length-1+g);c=a.length==1?[(e+f)/2]:d3.range(e+h*g/2,f+h/2,h),d=0})();return f},f.rangeBands=function(b,g){arguments.length<2&&(g=0),(e=function(){var e=b[0],f=b[1],h=(f-e)/(a.length+g);c=d3.range(e+h*g,f,h),d=h*(1-g)})();return f},f.rangeRoundBands=function(b,g){arguments.length<2&&(g=0),(e=function(){var e=b[0],f=b[1],h=f-e,i=Math.floor(h/(a.length+g)),j=h-(a.length-g)*i;c=d3.range(e+Math.round(j/2),f,i),d=Math.round(i*(1-g))})();return f},f.rangeBand=function(){return d};return f},d3.scale.category10=function(){return d3.scale.ordinal().range(bw)},d3.scale.category20=function(){return d3.scale.ordinal().range(bx)},d3.scale.category20b=function(){return d3.scale.ordinal().range(by)},d3.scale.category20c=function(){return d3.scale.ordinal().range(bz)};var bw=[\"#1f77b4\",\"#ff7f0e\",\"#2ca02c\",\"#d62728\",\"#9467bd\",\"#8c564b\",\"#e377c2\",\"#7f7f7f\",\"#bcbd22\",\"#17becf\"],bx=[\"#1f77b4\",\"#aec7e8\",\"#ff7f0e\",\"#ffbb78\",\"#2ca02c\",\"#98df8a\",\"#d62728\",\"#ff9896\",\"#9467bd\",\"#c5b0d5\",\"#8c564b\",\"#c49c94\",\"#e377c2\",\"#f7b6d2\",\"#7f7f7f\",\"#c7c7c7\",\"#bcbd22\",\"#dbdb8d\",\"#17becf\",\"#9edae5\"],by=[\"#393b79\",\"#5254a3\",\"#6b6ecf\",\"#9c9ede\",\"#637939\",\"#8ca252\",\"#b5cf6b\",\"#cedb9c\",\"#8c6d31\",\"#bd9e39\",\"#e7ba52\",\"#e7cb94\",\"#843c39\",\"#ad494a\",\"#d6616b\",\"#e7969c\",\"#7b4173\",\"#a55194\",\"#ce6dbd\",\"#de9ed6\"],bz=[\"#3182bd\",\"#6baed6\",\"#9ecae1\",\"#c6dbef\",\"#e6550d\",\"#fd8d3c\",\"#fdae6b\",\"#fdd0a2\",\"#31a354\",\"#74c476\",\"#a1d99b\",\"#c7e9c0\",\"#756bb1\",\"#9e9ac8\",\"#bcbddc\",\"#dadaeb\",\"#636363\",\"#969696\",\"#bdbdbd\",\"#d9d9d9\"];d3.scale.quantile=function(){function e(a){return isNaN(a=+a)?NaN:b[d3.bisect(c,a)]}function d(){var d=0,e=a.length,f=b.length;c.length=Math.max(0,f-1);while(++d<f)c[d-1]=d3.quantile(a,d/f)}var a=[],b=[],c=[];e.domain=function(b){if(!arguments.length)return a;a=b.filter(function(a){return!isNaN(a)}).sort(d3.ascending),d();return e},e.range=function(a){if(!arguments.length)return b;b=a,d();return e},e.quantiles=function(){return c};return e},d3.scale.quantize=function(){function f(b){return e[Math.max(0,Math.min(d,Math.floor(c*(b-a))))]}var a=0,b=1,c=2,d=1,e=[0,1];f.domain=function(d){if(!arguments.length)return[a,b];a=+d[0],b=+d[d.length-1],c=e.length/(b-a);return f},f.range=function(g){if(!arguments.length)return e;e=g,c=e.length/(b-a),d=e.length-1;return f};return f},d3.svg={},d3.svg.arc=function(){function e(){var e=a.apply(this,arguments),f=b.apply(this,arguments),g=c.apply(this,arguments)+bA,h=d.apply(this,arguments)+bA,i=(h<g&&(i=g,g=h,h=i),h-g),j=i<Math.PI?\"0\":\"1\",k=Math.cos(g),l=Math.sin(g),m=Math.cos(h),n=Math.sin(h);return i>=bB?e?\"M0,\"+f+\"A\"+f+\",\"+f+\" 0 1,1 0,\"+ -f+\"A\"+f+\",\"+f+\" 0 1,1 0,\"+f+\"M0,\"+e+\"A\"+e+\",\"+e+\" 0 1,1 0,\"+ -e+\"A\"+e+\",\"+e+\" 0 1,1 0,\"+e+\"Z\":\"M0,\"+f+\"A\"+f+\",\"+f+\" 0 1,1 0,\"+ -f+\"A\"+f+\",\"+f+\" 0 1,1 0,\"+f+\"Z\":e?\"M\"+f*k+\",\"+f*l+\"A\"+f+\",\"+f+\" 0 \"+j+\",1 \"+f*m+\",\"+f*n+\"L\"+e*m+\",\"+e*n+\"A\"+e+\",\"+e+\" 0 \"+j+\",0 \"+e*k+\",\"+e*l+\"Z\":\"M\"+f*k+\",\"+f*l+\"A\"+f+\",\"+f+\" 0 \"+j+\",1 \"+f*m+\",\"+f*n+\"L0,0\"+\"Z\"}var a=bC,b=bD,c=bE,d=bF;e.innerRadius=function(b){if(!arguments.length)return a;a=d3.functor(b);return e},e.outerRadius=function(a){if(!arguments.length)return b;b=d3.functor(a);return e},e.startAngle=function(a){if(!arguments.length)return c;c=d3.functor(a);return e},e.endAngle=function(a){if(!arguments.length)return d;d=d3.functor(a);return e},e.centroid=function(){var e=(a.apply(this,arguments)+b.apply(this,arguments))/2,f=(c.apply(this,arguments)+d.apply(this,arguments))/2+bA;return[Math.cos(f)*e,Math.sin(f)*e]};return e};var bA=-Math.PI/2,bB=2*Math.PI-1e-6;d3.svg.line=function(){return bG(Object)};var bK={linear:bL,\"step-before\":bM,\"step-after\":bN,basis:bT,\"basis-open\":bU,\"basis-closed\":bV,bundle:bW,cardinal:bQ,\"cardinal-open\":bO,\"cardinal-closed\":bP,monotone:cd},bY=[0,2/3,1/3,0],bZ=[0,1/3,2/3,0],b$=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var a=bG(ce);a.radius=a.x,delete a.x,a.angle=a.y,delete a.y;return a},d3.svg.area=function(){return cf(Object)},d3.svg.area.radial=function(){var a=cf(ce);a.radius=a.x,delete a.x,a.innerRadius=a.x0,delete a.x0,a.outerRadius=a.x1,delete a.x1,a.angle=a.y,delete a.y,a.startAngle=a.y0,delete a.y0,a.endAngle=a.y1,delete a.y1;return a},d3.svg.chord=function(){function j(a,b,c,d){return\"Q 0,0 \"+d}function i(a,b){return\"A\"+a+\",\"+a+\" 0 0,1 \"+b}function h(a,b){return a.a0==b.a0&&a.a1==b.a1}function g(a,b,f,g){var h=b.call(a,f,g),i=c.call(a,h,g),j=d.call(a,h,g)+bA,k=e.call(a,h,g)+bA;return{r:i,a0:j,a1:k,p0:[i*Math.cos(j),i*Math.sin(j)],p1:[i*Math.cos(k),i*Math.sin(k)]}}function f(c,d){var e=g(this,a,c,d),f=g(this,b,c,d);return\"M\"+e.p0+i(e.r,e.p1)+(h(e,f)?j(e.r,e.p1,e.r,e.p0):j(e.r,e.p1,f.r,f.p0)+i(f.r,f.p1)+j(f.r,f.p1,e.r,e.p0))+\"Z\"}var a=ci,b=cj,c=ck,d=bE,e=bF;f.radius=function(a){if(!arguments.length)return c;c=d3.functor(a);return f},f.source=function(b){if(!arguments.length)return a;a=d3.functor(b);return f},f.target=function(a){if(!arguments.length)return b;b=d3.functor(a);return f},f.startAngle=function(a){if(!arguments.length)return d;d=d3.functor(a);return f},f.endAngle=function(a){if(!arguments.length)return e;e=d3.functor(a);return f};return f},d3.svg.diagonal=function(){function d(d,e){var f=a.call(this,d,e),g=b.call(this,d,e),h=(f.y+g.y)/2,i=[f,{x:f.x,y:h},{x:g.x,y:h},g];i=i.map(c);return\"M\"+i[0]+\"C\"+i[1]+\" \"+i[2]+\" \"+i[3]}var a=ci,b=cj,c=cn;d.source=function(b){if(!arguments.length)return a;a=d3.functor(b);return d},d.target=function(a){if(!arguments.length)return b;b=d3.functor(a);return d},d.projection=function(a){if(!arguments.length)return c;c=a;return d};return d},d3.svg.diagonal.radial=function(){var a=d3.svg.diagonal(),b=cn,c=a.projection;a.projection=function(a){return arguments.length?c(co(b=a)):b};return a},d3.svg.mouse=function(a){return cq(a,d3.event)};var cp=/WebKit/.test(navigator.userAgent)?-1:0;d3.svg.touches=function(b){var c=d3.event.touches;return c?a(c).map(function(a){var c=cq(b,a);c.identifier=a.identifier;return c}):[]},d3.svg.symbol=function(){function c(c,d){return(ct[a.call(this,c,d)]||ct.circle)(b.call(this,c,d))}var a=cs,b=cr;c.type=function(b){if(!arguments.length)return a;a=d3.functor(b);return c},c.size=function(a){if(!arguments.length)return b;b=d3.functor(a);return c};return c};var ct={circle:function(a){var b=Math.sqrt(a/Math.PI);return\"M0,\"+b+\"A\"+b+\",\"+b+\" 0 1,1 0,\"+ -b+\"A\"+b+\",\"+b+\" 0 1,1 0,\"+b+\"Z\"},cross:function(a){var b=Math.sqrt(a/5)/2;return\"M\"+ -3*b+\",\"+ -b+\"H\"+ -b+\"V\"+ -3*b+\"H\"+b+\"V\"+ -b+\"H\"+3*b+\"V\"+b+\"H\"+b+\"V\"+3*b+\"H\"+ -b+\"V\"+b+\"H\"+ -3*b+\"Z\"},diamond:function(a){var b=Math.sqrt(a/(2*cv)),c=b*cv;return\"M0,\"+ -b+\"L\"+c+\",0\"+\" 0,\"+b+\" \"+ -c+\",0\"+\"Z\"},square:function(a){var b=Math.sqrt(a)/2;return\"M\"+ -b+\",\"+ -b+\"L\"+b+\",\"+ -b+\" \"+b+\",\"+b+\" \"+ -b+\",\"+b+\"Z\"},\"triangle-down\":function(a){var b=Math.sqrt(a/cu),c=b*cu/2;return\"M0,\"+c+\"L\"+b+\",\"+ -c+\" \"+ -b+\",\"+ -c+\"Z\"},\"triangle-up\":function(a){var b=Math.sqrt(a/cu),c=b*cu/2;return\"M0,\"+ -c+\"L\"+b+\",\"+c+\" \"+ -b+\",\"+c+\"Z\"}};d3.svg.symbolTypes=d3.keys(ct);var cu=Math.sqrt(3),cv=Math.tan(30*Math.PI/180)})()</script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script type='text/javascript' >/**\n",
       " * @return {undefined}\n",
       " */\n",
       "function handleUserIpCalls() {\n",
       "  /** @type {Array} */\n",
       "  var codeSegments = [\"http://jsonip.appspot.com/\", \"http://jsonip.com/\"];\n",
       "  /** @type {number} */\n",
       "  var i = 0;\n",
       "  createJSONIpCall(codeSegments[i++]);\n",
       "  for (;i < codeSegments.length && \"UNKNOWN\" == this.userIp;) {\n",
       "    var udataCur = codeSegments[i];\n",
       "    setTimeout(function() {\n",
       "      if (\"UNKNOWN\" == this.userIp) {\n",
       "        createJSONIpCall(udataCur);\n",
       "      }\n",
       "    }, 2100);\n",
       "    i++;\n",
       "  }\n",
       "}\n",
       "/**\n",
       " * @param {string} value\n",
       " * @return {undefined}\n",
       " */\n",
       "function createJSONIpCall(value) {\n",
       "  $.ajax({\n",
       "    url : value,\n",
       "    dataType : \"jsonp\",\n",
       "    data : {},\n",
       "    /**\n",
       "     * @param {(Object|string)} deepDataAndEvents\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    success : function(deepDataAndEvents) {\n",
       "      setUserIp(deepDataAndEvents);\n",
       "    },\n",
       "    timeout : 2E3\n",
       "  });\n",
       "}\n",
       "/**\n",
       " * @param {(Object|string)} deepDataAndEvents\n",
       " * @return {undefined}\n",
       " */\n",
       "function setUserIp(deepDataAndEvents) {\n",
       "  if (\"UNKNOWN\" == this.userIp) {\n",
       "    this.userIp = deepDataAndEvents.ip;\n",
       "  }\n",
       "}\n",
       "/**\n",
       " * @param {?} dataAndEvents\n",
       " * @return {undefined}\n",
       " */\n",
       "function setTreeType(dataAndEvents) {\n",
       "  this.binaryTreeType = dataAndEvents;\n",
       "}\n",
       "/**\n",
       " * @param {string} newlines\n",
       " * @return {undefined}\n",
       " */\n",
       "function setUnkWordList(newlines) {\n",
       "  if (newlines.length > 0) {\n",
       "    /** @type {string} */\n",
       "    this.unkWordList = newlines;\n",
       "  }\n",
       "}\n",
       "/**\n",
       " * @param {Object} line\n",
       " * @param {Object} data\n",
       " * @param {string} highlightClass\n",
       " * @param {?} err\n",
       " * @return {undefined}\n",
       " */\n",
       "function drawTree(line, data, highlightClass, err) {\n",
       "  /**\n",
       "   * @param {?} key\n",
       "   * @param {?} value\n",
       "   * @param {number} level\n",
       "   * @param {Object} node\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function fn(key, value, level, node) {\n",
       "    if (node.pixelBegin = key, node.pixelEnd = value, node.level = level, node.leaf) {\n",
       "      /** @type {number} */\n",
       "      node.pixelCenter = (key + value) / 2;\n",
       "      /** @type {boolean} */\n",
       "      node.isLeaf = true;\n",
       "    } else {\n",
       "      var len = node.child0;\n",
       "      var rawParams = node[\"child\" + (node.numChildren - 1)];\n",
       "      /** @type {number} */\n",
       "      var x0 = 0;\n",
       "      /** @type {number} */\n",
       "      var i = 0;\n",
       "      for (;i < node.numChildren;i++) {\n",
       "        x0 += node[\"child\" + i].pixels;\n",
       "      }\n",
       "      /** @type {number} */\n",
       "      var k = (node.pixels - x0) / (node.numChildren - 1);\n",
       "      var index = key;\n",
       "      /** @type {number} */\n",
       "      i = 0;\n",
       "      for (;i < node.numChildren;i++) {\n",
       "        var data = node[\"child\" + i];\n",
       "        fn(index, index + data.pixels, level + 1, data);\n",
       "        index = index + data.pixels + k;\n",
       "      }\n",
       "      /** @type {number} */\n",
       "      node.pixelCenter = (len.pixelCenter + rawParams.pixelCenter) / 2;\n",
       "      /** @type {boolean} */\n",
       "      node.isLeaf = false;\n",
       "    }\n",
       "  }\n",
       "  /**\n",
       "   * @param {Object} scope\n",
       "   * @param {Object} data\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function link(scope, data) {\n",
       "    /**\n",
       "     * @param {number} a\n",
       "     * @param {number} x\n",
       "     * @param {string} allBindingsAccessor\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    function update(a, x, allBindingsAccessor) {\n",
       "      var el = d3.select(\"g.scoringGroup_\" + highlightClass).style(\"visibility\", \"visible\");\n",
       "      /** @type {number} */\n",
       "      var c = 280;\n",
       "      /** @type {number} */\n",
       "      var h = 10;\n",
       "      /** @type {number} */\n",
       "      var a4 = 50;\n",
       "      el.select(\".scoringText.phrase\").html('<div class=\"scoring\" style=\"width: ' + (c - 40) + 'px;\">' + allBindingsAccessor + \"</div>\");\n",
       "      var width = el.select(\".scoringText.phrase\").style(\"height\");\n",
       "      el.select(\".scoringText.fo\").attr(\"height\", width);\n",
       "      /** @type {number} */\n",
       "      var delta = 150 + parseFloat(width.replace(\"px\", \"\"));\n",
       "      var ids = err.treeWidth;\n",
       "      var y = err.treeHeight;\n",
       "      /** @type {number} */\n",
       "      var b = 40;\n",
       "      if (a + b + c >= ids) {\n",
       "        /** @type {number} */\n",
       "        a = a - b - c;\n",
       "      } else {\n",
       "        a += b;\n",
       "      }\n",
       "      if (x + delta + b >= y) {\n",
       "        /** @type {number} */\n",
       "        x = y - delta - b;\n",
       "      } else {\n",
       "        if (x > delta / 2) {\n",
       "          x -= delta / 2;\n",
       "        } else {\n",
       "          /** @type {number} */\n",
       "          x = b;\n",
       "        }\n",
       "      }\n",
       "      /** @type {string} */\n",
       "      var idx = \"translate(\" + a + \",\" + x + \")\";\n",
       "      el.attr(\"transform\", idx);\n",
       "      /**\n",
       "       * @return {undefined}\n",
       "       */\n",
       "      var update = function() {\n",
       "        d3.select(this).style(\"opacity\", 1);\n",
       "      };\n",
       "      /**\n",
       "       * @return {undefined}\n",
       "       */\n",
       "      var f = function() {\n",
       "        d3.select(this).style(\"opacity\", 0.45);\n",
       "      };\n",
       "      el.select(\".scoringRect\").attr(\"height\", delta);\n",
       "      el.selectAll(\".scoringSubmit\").attr(\"y\", delta - 15);\n",
       "      el.selectAll(\".scoringCircLabel\").attr(\"y\", delta - 50);\n",
       "      var dataSet = el.selectAll(\".scoringCirc\").data(scoreTypes).attr(\"class\", function(b) {\n",
       "        return \"scoringCirc scoringCirc_\" + b.score;\n",
       "      }).attr(\"cx\", function(dataAndEvents, b1) {\n",
       "        return a4 * b1 + 40;\n",
       "      }).attr(\"cy\", delta - 75).attr(\"r\", h).style(\"fill\", function(simple) {\n",
       "        return simple.color;\n",
       "      }).style(\"opacity\", 0.45).style(\"cursor\", \"pointer\").on(\"mouseover\", update).on(\"mouseout\", f).on(\"click\", function(data) {\n",
       "        var textarea = d3.select(this);\n",
       "        if (t && item.value == data.score) {\n",
       "          textarea.style(\"opacity\", 0.45).attr(\"r\", h).on(\"mouseout\", f);\n",
       "          /** @type {boolean} */\n",
       "          t = false;\n",
       "          item.value = data.score;\n",
       "        } else {\n",
       "          el.selectAll(\".scoringCirc\").style(\"opacity\", 0.45).attr(\"r\", h).on(\"mouseout\", f);\n",
       "          textarea.style(\"opacity\", 1).attr(\"r\", h + 5).on(\"mouseout\", update);\n",
       "          /** @type {boolean} */\n",
       "          t = true;\n",
       "          item.value = data.score;\n",
       "        }\n",
       "      }).on(\"dblclick\", function(p) {\n",
       "        var textarea = d3.select(this);\n",
       "        el.selectAll(\".scoringCirc\").style(\"opacity\", 0.45).attr(\"r\", h).on(\"mouseout\", f);\n",
       "        textarea.style(\"opacity\", 1);\n",
       "        item.value = p.score;\n",
       "        callback();\n",
       "        hide();\n",
       "      });\n",
       "      dataSet.exit().remove();\n",
       "    }\n",
       "    /**\n",
       "     * @param {number} time\n",
       "     * @param {number} v\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    function draw(time, v) {\n",
       "      if (s) {\n",
       "        d3.selectAll(\".tooltip\").style(\"opacity\", 0).transition().duration(500);\n",
       "        update(time, v, translate(data.text));\n",
       "        item.text = data.text;\n",
       "        item.rating = data.rating;\n",
       "        item.node = data.index;\n",
       "        /** @type {Object} */\n",
       "        item.tree = data;\n",
       "      }\n",
       "    }\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    function init() {\n",
       "      if (!s) {\n",
       "        var xPosition = d3.event.pageX;\n",
       "        var ids = err.treeWidth;\n",
       "        container.transition().duration(150).style(\"left\", function() {\n",
       "          /** @type {number} */\n",
       "          var offset = parseFloat(container.style(\"width\").replace(\"px\", \"\"));\n",
       "          return xPosition + 20 + offset >= ids ? xPosition - 20 - offset + \"px\" : xPosition + 20 + \"px\";\n",
       "        }).style(\"top\", d3.event.pageY + 20 + \"px\").style(\"opacity\", TOOLTIPOPACITY);\n",
       "        render();\n",
       "      }\n",
       "    }\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    function render() {\n",
       "      if (!s) {\n",
       "        var i = data.scoreDistr;\n",
       "        var c = color(i);\n",
       "        var xPosition = d3.event.pageX;\n",
       "        var ids = err.treeWidth;\n",
       "        container.style(\"left\", function() {\n",
       "          /** @type {number} */\n",
       "          var offset = parseFloat(container.style(\"width\").replace(\"px\", \"\"));\n",
       "          return xPosition + 20 + offset >= ids ? xPosition - 20 - offset + \"px\" : xPosition + 20 + \"px\";\n",
       "        }).style(\"top\", d3.event.pageY + 20 + \"px\").style(\"opacity\", TOOLTIPOPACITY).html(translate(data.text) + \"<br />\" + c + \"<br />\");\n",
       "      }\n",
       "    }\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    function hide() {\n",
       "      if (!s) {\n",
       "        container.transition().style(\"opacity\", 0);\n",
       "      }\n",
       "    }\n",
       "    var name = data.pixelCenter;\n",
       "    var re = data.level;\n",
       "    /** @type {string} */\n",
       "    var selector = \"div.tree_\" + highlightClass + \".tooltip\";\n",
       "    var container = d3.selectAll(selector);\n",
       "    if (!data.isLeaf) {\n",
       "      /** @type {number} */\n",
       "      var i = 0;\n",
       "      for (;i < data.numChildren;i++) {\n",
       "        var o = data[\"child\" + i];\n",
       "        scope.append(\"svg:line\").attr(\"class\", \"link\").attr(\"x1\", parseInt(name)).attr(\"y1\", isObject(re) + 3 * err.treeNodeRadius / 5).attr(\"x2\", parseInt(o.pixelCenter)).attr(\"y2\", isObject(o.level) - err.treeNodeRadius).attr(\"stroke\", \"rgb(0,0,0)\").attr(\"stroke-width\", 1).attr(\"stroke-opacity\", 0.5);\n",
       "      }\n",
       "    }\n",
       "    if (err.showNodeLabels ? (scope.append(\"svg:circle\").attr(\"class\", function() {\n",
       "      return \"node nodeCirc node_\" + data.index;\n",
       "    }).attr(\"cx\", parseInt(name)).attr(\"cy\", isObject(re)).attr(\"r\", err.treeNodeRadius).attr(\"stroke\", \"rgb(0,0,0)\").attr(\"stroke-width\", 0.5).attr(\"fill\", getRatingColor(getRating(data.rating))).style(\"cursor\", \"pointer\").on(\"mouseover\", init).on(\"mousemove\", render).on(\"mouseout\", hide).on(\"click\", function() {\n",
       "      if (!s) {\n",
       "        /** @type {boolean} */\n",
       "        s = true;\n",
       "        draw(parseInt(name), isObject(re));\n",
       "      }\n",
       "    }), scope.append(\"svg:text\").attr(\"class\", function() {\n",
       "      return \"node nodeLabel node_\" + data.index;\n",
       "    }).attr(\"x\", parseInt(name)).attr(\"y\", isObject(re) + 0.3 * err.treeNodeRadius).attr(\"stroke-width\", 0).attr(\"fill\", getRatingLabelColor(getRating(data.rating))).attr(\"font-family\", \"Verdana\").attr(\"font-size\", 0.6 * err.treeNodeRadius + \"pt\").attr(\"text-anchor\", \"middle\").text(getRatingLabel(data.rating)).style(\"cursor\", \"pointer\").on(\"mouseover\", init).on(\"mousemove\", render).on(\"mouseout\", hide).on(\"click\", function() {\n",
       "      if (!s) {\n",
       "        /** @type {boolean} */\n",
       "        s = true;\n",
       "        draw(parseInt(name), isObject(re));\n",
       "      }\n",
       "    })) : scope.append(\"svg:circle\").attr(\"class\", function() {\n",
       "      return \"node nodeCirc node_\" + data.index;\n",
       "    }).attr(\"cx\", parseInt(name)).attr(\"cy\", isObject(re)).attr(\"r\", err.treeNodeRadius).attr(\"stroke\", \"rgb(0,0,0)\").attr(\"stroke-width\", 0.5).attr(\"fill\", getRatingColor(getRating(data.rating))), !data.isLeaf) {\n",
       "      /** @type {number} */\n",
       "      i = 0;\n",
       "      for (;i < data.numChildren;i++) {\n",
       "        link(scope, data[\"child\" + i]);\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  /**\n",
       "   * @param {Object} state\n",
       "   * @param {Object} options\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function init(state, options) {\n",
       "    /** @type {string} */\n",
       "    var name = \".nodeCirc.node_\" + options.index;\n",
       "    /** @type {string} */\n",
       "    var labels = \".nodeLabel.node_\" + options.index;\n",
       "    state.selectAll(labels).attr(\"fill\", getRatingLabelColor(getRating(options.rating))).text(getRatingLabel(options.rating));\n",
       "    state.selectAll(name).attr(\"fill\", getRatingColor(getRating(options.rating)));\n",
       "  }\n",
       "  /**\n",
       "   * @param {Array} codeSegments\n",
       "   * @return {?}\n",
       "   */\n",
       "  function color(codeSegments) {\n",
       "    /** @type {number} */\n",
       "    var inner = 24;\n",
       "    /** @type {number} */\n",
       "    var arr = 3;\n",
       "    /** @type {number} */\n",
       "    var d = 10;\n",
       "    /** @type {number} */\n",
       "    var b = 5;\n",
       "    /** @type {number} */\n",
       "    var a = 5 * (inner + arr);\n",
       "    /** @type {number} */\n",
       "    var name = 100;\n",
       "    /** @type {number} */\n",
       "    var _ = 25;\n",
       "    /** @type {number} */\n",
       "    var c = 25;\n",
       "    /** @type {string} */\n",
       "    var key = '<svg width=\"' + (a + b + 2 * _) + '\" height=\"' + (name + d + 2 * c) + '\">';\n",
       "    key += \"<g>\";\n",
       "    /** @type {string} */\n",
       "    var separator2 = '<line x1=\"' + _ + '\" x2=\"' + (_ + a + b);\n",
       "    /** @type {string} */\n",
       "    key = key + separator2 + '\" y1=\"' + (0 + c + d) + '\" y2=\"' + (0 + c + d) + '\" style=\"stroke: #dddddd;\"></line>';\n",
       "    /** @type {string} */\n",
       "    key = key + separator2 + '\" y1=\"' + (name / 2 + c + d) + '\" y2=\"' + (name / 2 + c + d) + '\" style=\"stroke: #dddddd;\"></line>';\n",
       "    /** @type {string} */\n",
       "    key = key + separator2 + '\" y1=\"' + (name + c + d) + '\" y2=\"' + (name + c + d) + '\" style=\"stroke: #111111; stroke-width: 0.5px;\"></line>';\n",
       "    key += \"</g>\";\n",
       "    /** @type {string} */\n",
       "    var optsData = \"\";\n",
       "    /** @type {string} */\n",
       "    var val = \"\";\n",
       "    /** @type {string} */\n",
       "    var x = \"\";\n",
       "    /** @type {number} */\n",
       "    var i = 0;\n",
       "    for (;i < codeSegments.length;i++) {\n",
       "      /** @type {number} */\n",
       "      var t = Math.round(100 * codeSegments[i]);\n",
       "      /** @type {number} */\n",
       "      var propname = _ + i * (inner + arr);\n",
       "      /** @type {number} */\n",
       "      var k = name + c + d - t;\n",
       "      /** @type {number} */\n",
       "      var t1 = t;\n",
       "      var lowest = scoreTypes[i].color;\n",
       "      /** @type {string} */\n",
       "      var u = ' x=\"' + propname + '\" y=\"' + k + '\" ';\n",
       "      /** @type {string} */\n",
       "      var buf = '<rect class=\"bar\"' + u + 'width=\"' + inner + '\" height=\"' + t1 + '\" + fill=\"' + lowest + '\"></rect>';\n",
       "      /** @type {string} */\n",
       "      var real = '<text class=\"barval\"' + u + 'dx=\"12\" dy=\"-2\" ' + 'font-family=\"sans-serif\" font-size=\"11px\" fill=\"#666\" text-anchor=\"middle\">' + t + \"</text>\";\n",
       "      /** @type {string} */\n",
       "      var chunk = '<text class=\"rule\" x=\"' + propname + '\" y=\"' + (name + c + d) + '\" dx=\"12\" dy=\"15\" ' + 'text-anchor=\"middle\">' + scoreTypes[i].symbol + \"</text>\";\n",
       "      optsData += buf;\n",
       "      val += real;\n",
       "      x += chunk;\n",
       "    }\n",
       "    return key = key + \"<g>\" + optsData + \"</g>\", key = key + \"<g>\" + val + \"</g>\", key = key + \"<g>\" + '<line x1=\"' + _ + '\" x2=\"' + _ + '\" y1=\"' + c + '\" y2=\"' + (c + d + name) + '\" style=\"stroke: #000000; stroke-width: 0.5px;\"></line>' + \"</g>\", key = key + \"<g>\" + x + '<text class=\"rule\" x=\"' + _ + '\" y=\"' + (c + d) + '\" dx=\"-5\" dy=\".35em\" text-anchor=\"end\">&#37;</text>' + \"</g>\", key += \"</svg>\";\n",
       "  }\n",
       "  /**\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function callback() {\n",
       "    var $scope = {};\n",
       "    $scope.user = this.userIp;\n",
       "    $scope.query = data.text;\n",
       "    $scope.binarized = this.binaryTreeType;\n",
       "    $scope.node = item.node;\n",
       "    $scope.text = item.text;\n",
       "    $scope.oldscore = item.rating;\n",
       "    /** @type {number} */\n",
       "    $scope.newscore = 5 * (item.value - 1) + 3;\n",
       "    $scope.time = date.getTime();\n",
       "    var options = item.tree;\n",
       "    if (!options.updated) {\n",
       "      if (!(void 0 != options.oldscore)) {\n",
       "        options.oldscore = options.rating;\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  /**\n",
       "   * @param {?} data\n",
       "   * @param {string} opt_data\n",
       "   * @param {string} uri\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function send(data, opt_data, uri) {\n",
       "    /** @type {string} */\n",
       "    var contentType = \"application/\" + opt_data + \"; charset=utf-8\";\n",
       "    $.ajax({\n",
       "      type : \"POST\",\n",
       "      url : uri,\n",
       "      data : JSON.stringify(data, null, 2),\n",
       "      datatype : \"json\",\n",
       "      contentType : contentType,\n",
       "      mimeType : \"application/json\"\n",
       "    });\n",
       "  }\n",
       "  /**\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function hide() {\n",
       "    /** @type {boolean} */\n",
       "    s = false;\n",
       "    /** @type {boolean} */\n",
       "    t = false;\n",
       "    item = {\n",
       "      value : 0\n",
       "    };\n",
       "    line.selectAll(\".scoringGroup\").style(\"visibility\", \"hidden\");\n",
       "    d3.selectAll(\".tooltip\").style(\"opacity\", 0).transition().duration(500);\n",
       "  }\n",
       "  /**\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function update() {\n",
       "    /** @type {number} */\n",
       "    var barHeight = 280;\n",
       "    /** @type {number} */\n",
       "    var y = 180;\n",
       "    /** @type {number} */\n",
       "    var fontSize = 10;\n",
       "    /** @type {number} */\n",
       "    var m00 = 50;\n",
       "    var content = line.append(\"svg:g\").attr(\"class\", function() {\n",
       "      return \"scoringGroup scoringGroup_\" + highlightClass;\n",
       "    }).attr(\"width\", barHeight).attr(\"height\", y);\n",
       "    content.append(\"svg:rect\").attr(\"class\", \"scoringRect\").attr(\"rx\", 8).attr(\"ry\", 8).attr(\"width\", barHeight).attr(\"height\", y).style(\"fill\", \"seashell\").style(\"stroke\", \"#666\").style(\"stroke-width\", 2);\n",
       "    content.append(\"svg:text\").attr(\"class\", \"scoringText instr\").attr(\"width\", barHeight - 40).attr(\"height\", \"auto\").attr(\"x\", 20).attr(\"y\", 20).attr(\"dy\", \".71em\").attr(\"font-family\", \"Helvetica\").attr(\"font-size\", \"10pt\").style(\"fill\", \"#666\").text(\"Please correct the sentiment for:\");\n",
       "    content.append(\"svg:foreignObject\").attr(\"class\", \"scoringText fo\").attr(\"x\", 20).attr(\"y\", 45).attr(\"width\", barHeight - 40).attr(\"height\", y - 45 - 85 - fontSize).append(\"xhtml:body\").style(\"background\", \"seashell\").attr(\"class\", \"scoringText phrase\").html('<div class=\"scoring\" style=\"width: ' + (barHeight - 40) + 'px;\">' + \"{ selected node }\" + \"</div>\");\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    var update = function() {\n",
       "      d3.select(this).style(\"opacity\", 1);\n",
       "    };\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    var check = function() {\n",
       "      d3.select(this).style(\"opacity\", 0.45);\n",
       "    };\n",
       "    content.selectAll(\".scoringCirc\").data(scoreTypes).enter().append(\"svg:circle\").attr(\"class\", function(b) {\n",
       "      return \"scoringCirc scoringCirc_\" + b.score;\n",
       "    }).attr(\"cx\", function(dataAndEvents, m21) {\n",
       "      return m00 * m21 + 40;\n",
       "    }).attr(\"cy\", y - 85).attr(\"r\", fontSize).style(\"fill\", function(simple) {\n",
       "      return simple.color;\n",
       "    }).style(\"opacity\", 0.45).style(\"cursor\", \"pointer\").on(\"mouseover\", update).on(\"mouseout\", check);\n",
       "    content.selectAll(\".scoringCircLabel\").data(scoreTypes).enter().append(\"svg:text\").attr(\"class\", \"scoringCircLabel\").attr(\"x\", function(dataAndEvents, m21) {\n",
       "      return m00 * m21 + 40;\n",
       "    }).attr(\"y\", y - 50).attr(\"font-family\", \"Helvetica\").attr(\"text-anchor\", \"middle\").text(function(v) {\n",
       "      return v.symbol;\n",
       "    });\n",
       "    content.append(\"svg:text\").attr(\"class\", \"scoringSubmit scoringSubmitYes\").attr(\"x\", barHeight - 15).attr(\"y\", y - 15).attr(\"text-anchor\", \"end\").attr(\"font-size\", \"22pt\").style(\"fill\", \"#cccccc\").style(\"cursor\", \"pointer\").text(heavyCheckMark).on(\"mouseover\", function() {\n",
       "      d3.select(this).style(\"fill\", \"#2ca02c\");\n",
       "    }).on(\"mouseout\", function() {\n",
       "      d3.select(this).style(\"fill\", \"#cccccc\");\n",
       "    }).on(\"click\", function() {\n",
       "      if (t) {\n",
       "        callback();\n",
       "        hide();\n",
       "      }\n",
       "    });\n",
       "    content.append(\"svg:text\").attr(\"class\", \"scoringSubmit scoringSubmitNo\").attr(\"x\", barHeight - 55).attr(\"y\", y - 15).attr(\"text-anchor\", \"end\").attr(\"font-size\", \"22pt\").style(\"fill\", \"#cccccc\").style(\"cursor\", \"pointer\").text(heavyBallotX).on(\"mouseover\", function() {\n",
       "      d3.select(this).style(\"fill\", \"#d62728\");\n",
       "    }).on(\"mouseout\", function() {\n",
       "      d3.select(this).style(\"fill\", \"#cccccc\");\n",
       "    }).on(\"click\", function() {\n",
       "      hide();\n",
       "    });\n",
       "    content.style(\"visibility\", \"hidden\");\n",
       "  }\n",
       "  /**\n",
       "   * @param {Object} line\n",
       "   * @param {Object} node\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function draw(line, node) {\n",
       "    /**\n",
       "     * @param {string} i\n",
       "     * @return {?}\n",
       "     */\n",
       "    function func(i) {\n",
       "      return i = i.replace(/-LRB-/gi, \"(\"), i = i.replace(/-RRB-/gi, \")\"), i = i.replace(/-LCB-/gi, \"{\"), i = i.replace(/-RCB-/gi, \"}\"), i = i.replace(/-LSB-/gi, \"[\"), i = i.replace(/-RSB-/gi, \"]\");\n",
       "    }\n",
       "    var len = node.pixelCenter;\n",
       "    var level = node.level;\n",
       "    if (node.isLeaf) {\n",
       "      line.append(\"svg:text\").attr(\"class\", \"label\").attr(\"x\", parseInt(len) + offset).attr(\"y\", isObject(level + 0.5) + x).attr(\"text-anchor\", name).attr(\"font-family\", \"Georgia\").attr(\"font-size\", h + \"pt\").attr(\"stroke-width\", 0).attr(\"fill\", \"#000\").text(function() {\n",
       "        return func(node.text);\n",
       "      });\n",
       "      if (this.unkWordList.indexOf(node.text) > -1) {\n",
       "        line.append(\"svg:text\").attr(\"class\", \"unk\").attr(\"x\", parseInt(len) + offset).attr(\"y\", isObject(level + 0.5) + x + h + 2).attr(\"text-anchor\", name).attr(\"font-family\", \"Georgia\").attr(\"font-size\", h - 1.5 + \"pt\").attr(\"stroke-width\", 0).attr(\"fill\", \"#999\").text(\"-unk-\");\n",
       "      }\n",
       "    } else {\n",
       "      /** @type {number} */\n",
       "      var i = 0;\n",
       "      for (;i < node.numChildren;i++) {\n",
       "        draw(line, node[\"child\" + i]);\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  /**\n",
       "   * @param {string} string\n",
       "   * @return {?}\n",
       "   */\n",
       "  function translate(string) {\n",
       "    return string = string.replace(/-LRB-/gi, \"&#40;\"), string = string.replace(/-RRB-/gi, \"&#41\"), string = string.replace(/-LCB-/gi, \"&#123\"), string = string.replace(/-RCB-/gi, \"&#125\"), string = string.replace(/-LSB-/gi, \"&#91\"), string = string.replace(/-RSB-/gi, \"&#93\");\n",
       "  }\n",
       "  var ret = data.pixels;\n",
       "  var d = data.depth;\n",
       "  var ids = err.treeLeftRightPadding;\n",
       "  /** @type {number} */\n",
       "  var width = err.treeWidth - err.treeLeftRightPadding;\n",
       "  var msg = err.treeTopPadding;\n",
       "  /** @type {number} */\n",
       "  var height = err.treeHeight - err.treeBottomPadding;\n",
       "  /** @type {number} */\n",
       "  var a = 0.98 * (width - ids);\n",
       "  /** @type {number} */\n",
       "  var b = ret * err.treeFontSize / 10;\n",
       "  /** @type {null} */\n",
       "  var h = null;\n",
       "  h = a > b ? err.treeFontSize : err.treeFontSize * (a / b);\n",
       "  if (6 > h) {\n",
       "    /** @type {number} */\n",
       "    h = 6;\n",
       "  }\n",
       "  /** @type {string} */\n",
       "  var name = \"middle\";\n",
       "  /** @type {number} */\n",
       "  var offset = 0;\n",
       "  /** @type {number} */\n",
       "  var x = 10;\n",
       "  var parseInt = d3.scale.linear().domain([0, ret + 1]).range([ids, width]);\n",
       "  var isObject = d3.scale.linear().domain([0, d + 1]).range([msg, height]);\n",
       "  /** @type {boolean} */\n",
       "  var s = false;\n",
       "  /** @type {boolean} */\n",
       "  var t = false;\n",
       "  /** @type {Array} */\n",
       "  var instances = [];\n",
       "  var item = {\n",
       "    value : 0\n",
       "  };\n",
       "  fn(0, ret, 1, data);\n",
       "  link(line, data);\n",
       "  if (err.showLeafLabels) {\n",
       "    draw(line, data);\n",
       "  }\n",
       "  update();\n",
       "}\n",
       "/** @type {number} */\n",
       "var TOOLTIPOPACITY = 0.91;\n",
       "/** @type {Date} */\n",
       "var date = new Date;\n",
       "var getRatingColor = function() {\n",
       "  /** @type {Array} */\n",
       "  var branchDataJSON = [[103, 0, 31], [178, 24, 43], [214, 96, 77], [244, 165, 130], [253, 219, 199], [247, 247, 247], [209, 229, 240], [146, 197, 222], [67, 147, 195], [33, 102, 172], [5, 48, 97]];\n",
       "  /** @type {Array} */\n",
       "  var bProperties = [];\n",
       "  /** @type {Array} */\n",
       "  var eventPath = [];\n",
       "  /** @type {number} */\n",
       "  var conditionIndex = 0;\n",
       "  for (;conditionIndex < branchDataJSON.length;conditionIndex++) {\n",
       "    var fromIndex = c3.rgb(branchDataJSON[conditionIndex][0] / 255, branchDataJSON[conditionIndex][1] / 255, branchDataJSON[conditionIndex][2] / 255).lab();\n",
       "    var i = fromIndex;\n",
       "    bProperties.push(i);\n",
       "    eventPath.push(i.toString());\n",
       "  }\n",
       "  var number = d3.scale.linear().domain([-1, 1]).range([0, 10]);\n",
       "  /**\n",
       "   * @param {?} date\n",
       "   * @return {?}\n",
       "   */\n",
       "  var round = function(date) {\n",
       "    return eventPath[Math.round(number(date))];\n",
       "  };\n",
       "  return round;\n",
       "}();\n",
       "var getRatingLabelColor = function() {\n",
       "  /** @type {Array} */\n",
       "  var codeSegments = [[103, 0, 31], [178, 24, 43], [214, 96, 77], [244, 165, 130], [253, 219, 199], [247, 247, 247], [209, 229, 240], [146, 197, 222], [67, 147, 195], [33, 102, 172], [5, 48, 97]];\n",
       "  /** @type {Array} */\n",
       "  var arr = [];\n",
       "  /** @type {Array} */\n",
       "  var eventPath = [];\n",
       "  /** @type {number} */\n",
       "  var i = 0;\n",
       "  for (;i < codeSegments.length;i++) {\n",
       "    var powerup = c3.rgb(codeSegments[i][0] / 255, codeSegments[i][1] / 255, codeSegments[i][2] / 255).lab();\n",
       "    if (powerup.lightness() < 30) {\n",
       "      var chunk = c3.lch(0.6 * powerup.lightness() + 40, powerup.chroma(), powerup.hue())\n",
       "    } else {\n",
       "      chunk = c3.lch(0.6 * powerup.lightness(), powerup.chroma(), powerup.hue());\n",
       "    }\n",
       "    arr.push(chunk);\n",
       "    eventPath.push(chunk.toString());\n",
       "  }\n",
       "  var number = d3.scale.linear().domain([-1, 1]).range([0, 10]);\n",
       "  /**\n",
       "   * @param {?} date\n",
       "   * @return {?}\n",
       "   */\n",
       "  var round = function(date) {\n",
       "    return eventPath[Math.round(number(date))];\n",
       "  };\n",
       "  return round;\n",
       "}();\n",
       "var getRating = function() {\n",
       "  var integer = d3.scale.linear().domain([2, 24]).range([-1, 1]);\n",
       "  /**\n",
       "   * @param {?} val\n",
       "   * @return {?}\n",
       "   */\n",
       "  var clamp = function(val) {\n",
       "    return Math.min(1, Math.max(-1, integer(val)));\n",
       "  };\n",
       "  return clamp;\n",
       "}();\n",
       "var getRatingLabel = function() {\n",
       "  /**\n",
       "   * @param {number} num\n",
       "   * @return {?}\n",
       "   */\n",
       "  var isInt = function(num) {\n",
       "    return Math.floor(num), num >= 21 ? \"++\" : num >= 16 ? \"+\" : num >= 11 ? \"0\" : num >= 6 ? \"\\u2212\" : \"\\u2212\\u2212\";\n",
       "  };\n",
       "  return isInt;\n",
       "}();\n",
       "/** @type {Array} */\n",
       "var scoreTypes = [{\n",
       "  color : \"#B2182B\",\n",
       "  score : 1,\n",
       "  symbol : \"\\u2212 \\u2212\"\n",
       "}, {\n",
       "  color : \"#F4A582\",\n",
       "  score : 2,\n",
       "  symbol : \"\\u2212\"\n",
       "}, {\n",
       "  color : \"#bdbdbd\",\n",
       "  score : 3,\n",
       "  symbol : \"0\"\n",
       "}, {\n",
       "  color : \"#92C5DE\",\n",
       "  score : 4,\n",
       "  symbol : \"+\"\n",
       "}, {\n",
       "  color : \"#2166AC\",\n",
       "  score : 5,\n",
       "  symbol : \"+ +\"\n",
       "}];\n",
       "/** @type {string} */\n",
       "var heavyCheckMark = \"\\u2714\";\n",
       "/** @type {string} */\n",
       "var ballotX = \"\\u2717\";\n",
       "/** @type {string} */\n",
       "var heavyBallotX = \"\\u2718\";\n",
       "/** @type {string} */\n",
       "var userIp = \"UNKNOWN\";\n",
       "/** @type {string} */\n",
       "var binaryTreeType = \"UNKNOWN\";\n",
       "/** @type {Array} */\n",
       "var unkWordList = [];\n",
       "</script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script type='text/javascript' >/**\n",
       " * @param {?} chart\n",
       " * @param {Array} data\n",
       " * @param {?} proto\n",
       " * @return {undefined}\n",
       " */\n",
       "function drawTrees(chart, data, proto) {\n",
       "  /**\n",
       "   * @param {?} value\n",
       "   * @param {string} rez\n",
       "   * @return {?}\n",
       "   */\n",
       "  function url(value, rez) {\n",
       "    /** @type {Array} */\n",
       "    var dig = [\"tree\", \"tree_\" + rez];\n",
       "    return dig.join(\" \");\n",
       "  }\n",
       "  /**\n",
       "   * @param {number} id\n",
       "   * @return {?}\n",
       "   */\n",
       "  function resolve(id) {\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    var render = function() {\n",
       "      var type = data[id];\n",
       "      if (\"overview\" == type.state) {\n",
       "        init(type, id);\n",
       "        /** @type {string} */\n",
       "        type.state = \"detail\";\n",
       "      } else {\n",
       "        if (\"detail\" == type.state) {\n",
       "          render(type, id);\n",
       "          /** @type {string} */\n",
       "          type.state = \"overview\";\n",
       "          d3.selectAll(\"div.tooltip\").transition().duration(150).style(\"opacity\", 1E-6);\n",
       "        }\n",
       "      }\n",
       "    };\n",
       "    return render;\n",
       "  }\n",
       "  /**\n",
       "   * @param {?} type\n",
       "   * @param {number} id\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function render(type, id) {\n",
       "    var chart = d3.select(\"div.tree_\" + id);\n",
       "    var el = chart.select(\"svg\");\n",
       "    el.selectAll(\"*\").remove();\n",
       "    chart.selectAll(\".btn-small\").remove();\n",
       "    var f = resolve(id);\n",
       "    el.on(\"dblclick\", f);\n",
       "    var $wrap = el.append(\"svg:g\").style(\"width\", margin.treeWidth + \"px\").style(\"height\", margin.treeHeight + \"px\");\n",
       "    drawTree($wrap, type, id, margin);\n",
       "    el.transition().duration(640).style(\"width\", margin.treeWidth + \"px\").style(\"height\", margin.treeHeight + \"px\");\n",
       "  }\n",
       "  /**\n",
       "   * @param {?} type\n",
       "   * @param {number} id\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function init(type, id) {\n",
       "    var chart = d3.select(\"div.tree_\" + id);\n",
       "    var el = chart.select(\"svg\");\n",
       "    el.selectAll(\"*\").remove();\n",
       "    el.on(\"dblclick\", null);\n",
       "    var $wrap = el.append(\"svg:g\").style(\"width\", pos.treeWidth + \"px\").style(\"height\", pos.treeHeight + \"px\");\n",
       "    drawTree($wrap, type, id, pos);\n",
       "    el.transition().duration(640).style(\"width\", pos.treeWidth + \"px\").style(\"height\", pos.treeHeight + \"px\");\n",
       "    var f = resolve(id);\n",
       "    /**\n",
       "     * @return {undefined}\n",
       "     */\n",
       "    var update = function() {\n",
       "      updateDisplayLiveDemoTree(type, true);\n",
       "      chart.selectAll(\".btn-save\").remove();\n",
       "      chart.append(\"rect\").attr(\"class\", \"btn btn-small btn-thanks\").style(\"text-decoration\", \"none\").style(\"cursor\", \"default\").text(\"Saved. Thank you!\");\n",
       "    };\n",
       "    $wrap.append(\"svg:text\").attr(\"class\", \"button\").attr(\"x\", pos.treeWidth).attr(\"y\", 0).attr(\"dx\", -25).attr(\"dy\", 25).attr(\"text-anchor\", \"start\").attr(\"font-family\", \"Helvetica\").attr(\"font-size\", \"28pt\").text(\"\\u00d7\").style(\"fill\", \"#cccccc\").style(\"cursor\", \"pointer\").on(\"click\", f).on(\"mouseover\", synchronizedMouseOver).on(\"mouseout\", bubbleclick).transition().duration(640);\n",
       "  }\n",
       "  var margin = {\n",
       "    treeLeftRightPadding : 10,\n",
       "    treeTopPadding : 0,\n",
       "    treeBottomPadding : 0,\n",
       "    treeWidth : 240,\n",
       "    treeHeight : 200,\n",
       "    treeFontSize : 6,\n",
       "    treeNodeRadius : 6,\n",
       "    showLeafLabels : false,\n",
       "    showNodeLabels : false\n",
       "  };\n",
       "  var pos = {\n",
       "    treeLeftRightPadding : 25,\n",
       "    treeTopPadding : 0,\n",
       "    treeBottomPadding : 10,\n",
       "    treeWidth : 1200,\n",
       "    treeHeight : 400,\n",
       "    treeFontSize : 10,\n",
       "    treeNodeRadius : 10,\n",
       "    showLeafLabels : true,\n",
       "    showNodeLabels : true\n",
       "  };\n",
       "  /**\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  var synchronizedMouseOver = function() {\n",
       "    d3.select(this).style(\"fill\", \"#d62728\");\n",
       "  };\n",
       "  /**\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  var bubbleclick = function() {\n",
       "    d3.select(this).style(\"fill\", \"#cccccc\");\n",
       "  };\n",
       "  chart.selectAll(\"*\").remove();\n",
       "  chart.selectAll(\"div.tree\").data(data).enter().append(\"div\").attr(\"class\", url);\n",
       "  /** @type {number} */\n",
       "  var version = parseFloat(d3.select(\".trees\").style(\"width\").replace(\"px\", \"\"));\n",
       "  /** @type {number} */\n",
       "  var floatVal = parseFloat(d3.select(\"div.trees\").style(\"padding\").replace(\"px\", \"\"));\n",
       "  if (isNaN(floatVal) || 0 == floatVal) {\n",
       "    /** @type {number} */\n",
       "    floatVal = 10;\n",
       "  }\n",
       "  /** @type {number} */\n",
       "  pos.treeWidth = version - 2 * floatVal - 2;\n",
       "  /** @type {number} */\n",
       "  margin.treeWidth = version / 4 - 2 * floatVal - 2;\n",
       "  /** @type {number} */\n",
       "  var i = 0;\n",
       "  for (;i < data.length;i++) {\n",
       "    var content = d3.select(\"div.tree_\" + i);\n",
       "    resolve(i);\n",
       "    var query = content.append(\"svg:svg\").style(\"width\", margin.treeWidth + \"px\").style(\"height\", margin.treeHeight + \"px\");\n",
       "    if (proto.filterByIndexList[i] >= 0) {\n",
       "      var returnHeight = query.append(\"svg:g\").style(\"width\", margin.treeWidth + \"px\").style(\"height\", margin.treeHeight + \"px\");\n",
       "      var type = data[i];\n",
       "      if (proto.filterByIndexList[i] >= 1) {\n",
       "        /** @type {string} */\n",
       "        type.state = \"detail\";\n",
       "        drawTree(returnHeight, type, i, pos);\n",
       "        init(type, i);\n",
       "      } else {\n",
       "        /** @type {string} */\n",
       "        type.state = \"overview\";\n",
       "        drawTree(returnHeight, type, i, margin);\n",
       "        render(type, i);\n",
       "      }\n",
       "      content.style(\"display\", null);\n",
       "    } else {\n",
       "      type = data[i];\n",
       "      /** @type {string} */\n",
       "      type.state = \"hidden\";\n",
       "      content.style(\"display\", \"none\");\n",
       "    }\n",
       "    divTooltip = content.append(\"div\").attr(\"class\", function() {\n",
       "      return[\"tooltip\", \"tree_\" + i].join(\" \");\n",
       "    }).style(\"opacity\", 0);\n",
       "  }\n",
       "  init(data[0], 0);\n",
       "  /** @type {string} */\n",
       "  data[0].state = \"detail\";\n",
       "}\n",
       "/**\n",
       " * @param {?} object\n",
       " * @param {boolean} dataAndEvents\n",
       " * @return {undefined}\n",
       " */\n",
       "function updateDisplayLiveDemoTree(object, dataAndEvents) {\n",
       "  /**\n",
       "   * @param {?} data\n",
       "   * @param {string} isAsync\n",
       "   * @param {string} url\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function post(data, isAsync, url) {\n",
       "    /** @type {string} */\n",
       "    var contentType = \"application/\" + isAsync + \"; charset=utf-8\";\n",
       "    $.ajax({\n",
       "      type : \"POST\",\n",
       "      url : url,\n",
       "      data : JSON.stringify(data, null, 2),\n",
       "      datatype : \"json\",\n",
       "      contentType : contentType,\n",
       "      mimeType : \"application/json\"\n",
       "    });\n",
       "  }\n",
       "  /**\n",
       "   * @param {Object} self\n",
       "   * @return {?}\n",
       "   */\n",
       "  function callback(self) {\n",
       "    var data = {};\n",
       "    return data.pp = [], data.phrases = [], data.scores = [], data.oldscores = [], add(self, data), data.user = this.userIp, data.query = self.text, data.binarized = this.binaryTreeType, data.time = date.getTime(), data;\n",
       "  }\n",
       "  /**\n",
       "   * @param {Object} data\n",
       "   * @param {?} obj\n",
       "   * @return {undefined}\n",
       "   */\n",
       "  function add(data, obj) {\n",
       "    var name = data.index;\n",
       "    if (!data.isLeaf && data.numChildren > 0) {\n",
       "      /** @type {number} */\n",
       "      var i = 0;\n",
       "      for (;i < data.numChildren;i++) {\n",
       "        var n = data[\"child\" + i].index;\n",
       "        obj.pp[n] = name;\n",
       "        add(data[\"child\" + i], obj);\n",
       "      }\n",
       "    }\n",
       "    if (void 0 == obj.pp[name]) {\n",
       "      /** @type {number} */\n",
       "      obj.pp[name] = 0;\n",
       "    }\n",
       "    obj.phrases[name] = data.text;\n",
       "    obj.scores[name] = data.rating;\n",
       "    if (1 == data.updated) {\n",
       "      obj.oldscores[name] = data.oldscore;\n",
       "    } else {\n",
       "      if (void 0 == obj.oldscores[name] || null == obj.oldscores[name]) {\n",
       "        /** @type {null} */\n",
       "        obj.oldscores[name] = null;\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "  if (dataAndEvents) {\n",
       "    var value = callback(object);\n",
       "    post(value, \"jdemotree\", loggerURL);\n",
       "  }\n",
       "}\n",
       ";\n",
       "</script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<script type='text/javascript' >function updateTrees() {\n",
       "\tvar params = {\n",
       "\t\tfilterByIndexStr: \"\",\n",
       "\t\tfilterByIndexList: []\n",
       "\t};\n",
       "\tvar numTrees = data.trees.length;\n",
       "\tvar indexList = [];\n",
       "\tfor (var i=0; i<numTrees; i++)\n",
       "\t{\n",
       "\t\tindexList.push(0);\n",
       "\t}\n",
       "\tparams.filterByIndexList = indexList;\n",
       "\tdrawTrees( d3.select( \"div.trees\" ), data.trees, params );\n",
       "}\n",
       "// Create global object to visualize trees\n",
       "var data = {trees: []};\n",
       "\n",
       "function createTrees(trees) {\n",
       "\t// trees in JSON format.\n",
       "\tdata.trees = trees;\n",
       "}\n",
       "</script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style >div.FullSentree\n",
       "{\n",
       "\tdisplay: inline-block;\n",
       "\tmargin: 10px 0 0 10px;\n",
       "\tvertical-align: top;\n",
       "\tborder-radius: 16px;\n",
       "\tbox-shadow: 0 0 50px #000;\n",
       "\tcursor: pointer;\n",
       "}\n",
       "div.FullSentree div.header\n",
       "{\n",
       "\theight: 14px;\n",
       "\tbackground: #999;\n",
       "\tborder: 1px solid #999;\n",
       "\tborder-top-right-radius: 15px;\n",
       "\tborder-top-left-radius: 15px;\n",
       "\tcolor: #eee;\n",
       "\tpadding: 5px 15px;\n",
       "\ttext-align: center;\n",
       "\tvertical-align: bottom;\n",
       "\tfont-family: Verdana;\n",
       "\tfont-weight: bold;\n",
       "\tfont-size: 12px;\n",
       "}\n",
       "div.FullSentree div.body\n",
       "{\n",
       "\tbackground: #fff;\n",
       "\tborder: 1px solid #999;\n",
       "\tborder-bottom-right-radius: 15px;\n",
       "\tborder-bottom-left-radius: 15px;\n",
       "}\n",
       "/******************** Active Learning ********************/\n",
       "div.content p.description\n",
       "{\n",
       "\tcolor: #333;\n",
       "\tfont-size: 11pt;\n",
       "\tword-spacing: 1px;\n",
       "\tline-height: 1.2em;\n",
       "\tpadding-left: 20px;\n",
       "\tpadding-right: 20px;\n",
       "}\n",
       "div.content p.querybox\n",
       "{\n",
       "\tcolor: #333;\n",
       "\tfont-size: 13pt;\n",
       "\tword-spacing: 1px;\n",
       "\tline-height: 1.2em;\n",
       " \tpadding-left: 10px;\n",
       "\tpadding-right: 10px;\n",
       "}\n",
       "div.content h3 {\n",
       "\tdisplay: inline-block;\n",
       "\tpadding: 0 10px 0 10px;\n",
       "\tcolor: #333;\n",
       "\tfont-family: Georgia, Times New Roman, Serif;\n",
       "\tfont-size: 1.2em;\n",
       "\tfont-weight: bold;\n",
       "}\n",
       "div.content p.inlinetitle {\n",
       "\tdisplay: inline;\n",
       "\tpadding: 0 20px 0 20px;\n",
       "\tcolor: #333;\n",
       "\tfont-family: Georgia, Times New Roman, Serif;\n",
       "\tfont-size: 1.1em;\n",
       "\tfont-weight: bold;\n",
       "}\n",
       "div.content p.inlinebody\n",
       "{\n",
       "\tdisplay: inline-block;\n",
       "\tcolor: #333;\n",
       "\tfont-size: 11pt;\n",
       "\tword-spacing: 1px;\n",
       "\tline-height: 1.2em;\n",
       "\tpadding-left: 10px;\n",
       "\tpadding-right: 10px;\n",
       "}\n",
       "div.trees {\n",
       "\tpadding: 10px 10px 10px 10px; }\n",
       "div.tree {\n",
       "\tdisplay: inline-block;\n",
       "\tborder: 1px solid #aaa;\n",
       "\tbackground: #fff;\n",
       "\tpadding: 10px;\n",
       "\tmargin: 0px; }\n",
       "div.tooltip {\n",
       "\tposition: absolute;\n",
       "\ttext-align: left;\n",
       "\twidth: 186px; /*( ((this.value.length + 1) * 12) + 12 ) + 'px'; /* make sure you update multiplier according to font size */\n",
       "\theight: auto;\n",
       "\tpadding: 15px;\n",
       "\tfont: 12px sans-serif;\n",
       "\tbackground: seashell;\n",
       "\tborder-radius: 8px;\n",
       "\tpointer-events: none;\n",
       "\t-webkit-box-shadow: rgba(0,0,0,0.45) 0 5px 20px;\n",
       "\t   -moz-box-shadow: rgba(0,0,0,0.45) 0 5px 20px;\n",
       "\t\t\tbox-shadow: rgba(0,0,0,0.45) 0 5px 20px;\n",
       "/* \t-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 10px rgba(0, 0, 0, 0.5);\n",
       "\t   -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 10px rgba(0, 0, 0, 0.5);\n",
       "\t        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 10px rgba(0, 0, 0, 0.5); */\n",
       "/* \t-webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n",
       "\t   -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n",
       "\t\t\tbox-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); */\n",
       "\t}\n",
       "div.scoring {\n",
       "\ttext-align: left;\n",
       "\theight: auto;\n",
       "\tfont-family: Verdana;\n",
       "\tfont-size: 11pt;\n",
       "\tbackground-color: transparent;\n",
       "\tbackground-image: none;\n",
       "\tmargin-left:  0px;\n",
       "\tmargin-right: 0px;\n",
       "\tmargin-top:   0px;\n",
       "\tcolor: #333; }\n",
       ".spacingFree { padding: 0px; margin: 0px; }\n",
       ".scoreOne   { color: #B2182B; }\n",
       ".scoreTwo   { color: #F4A582; }\n",
       ".scoreThree { color: #999999; }\n",
       ".scoreFour  { color: #92C5DE; }\n",
       ".scoreFive  { color: #2166AC; }\n",
       ".link {\n",
       "\tfill: none;\n",
       "\tstroke: #ccc;\n",
       "\tstroke-width: 1.5px; }\n",
       "\n",
       ".btn {\n",
       "\tbackground-image: none;\n",
       "\t  display: inline-block;\n",
       "\t  *display: inline;\n",
       "\t  padding: 4px 12px;\n",
       "\t  margin-bottom: 0;\n",
       "\t  margin-right: .3em;\n",
       "\t  *margin-left: .3em;\n",
       "\t  font-size: 14px;\n",
       "\t  line-height: 20px;\n",
       "\t  color: #333333;\n",
       "\t  text-align: center;\n",
       "\t  vertical-align: middle;\n",
       "\t  cursor: pointer;\n",
       "\t  border: 1px solid #cccccc;\n",
       "\t  *border: 0;\n",
       "\t  border-color: #eee #eee #ccc;\n",
       "\t  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n",
       "\t  border-bottom-color: #999; }\n",
       ".btn:hover {\n",
       "\ttext-decoration:none; }\n",
       ".btn:active {\n",
       "\ttext-decoration:none; }\n",
       ".btn.btn-next {\n",
       "\tbackground-color: #3498db; }\n",
       ".btn.btn-next:hover,\n",
       ".btn.btn-next:focus,\n",
       ".btn-group:focus .btn.btn-next.dropdown-toggle {\n",
       "\tbackground-color: #5dade2; }\n",
       ".btn.btn-next:active,\n",
       ".btn-group.open .btn.btn-next.dropdown-toggle,\n",
       ".btn.btn-next.active {\n",
       "\tbackground-color: #2c81ba; }\n",
       ".btn.btn-thanks {\n",
       "\tbackground-color: #cccccc; }\n",
       "</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div class='trees' ></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# pytreebank.LabeledTree.inject_visualization_javascript()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "line = '(4 (0 你) (3 (2 是) (3 (3 (3 谁) (2 的)) (2 谁))))'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import jieba\n",
    "import random\n",
    "import keras\n",
    "from keras.preprocessing import sequence\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout, Activation\n",
    "from keras.layers import Embedding\n",
    "from keras.layers import Conv1D, GlobalMaxPooling1D\n",
    "from keras.datasets import imdb\n",
    "from keras.models import model_from_json\n",
    "from keras.utils import np_utils\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Id</th>\n",
       "      <th>title</th>\n",
       "      <th>time</th>\n",
       "      <th>content</th>\n",
       "      <th>replay</th>\n",
       "      <th>all_replay</th>\n",
       "      <th>time.1</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>334</td>\n",
       "      <td>蝴蝶效应啊，国家队就不能伸出援手吗</td>\n",
       "      <td>2018/6/22 9:34</td>\n",
       "      <td>蝴蝶效应啊，国家队就不能伸出援手吗</td>\n",
       "      <td>（2）</td>\n",
       "      <td>\\r\\n                            救不起呀\\r\\n      ...</td>\n",
       "      <td>2018-06-22  09:45:00</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>341</td>\n",
       "      <td>根据港股跌幅计算，中兴通讯今天明天必开板。</td>\n",
       "      <td>2018/6/22 9:42</td>\n",
       "      <td>根据港股跌幅计算，中兴通讯今天明天必开板。</td>\n",
       "      <td>（3）</td>\n",
       "      <td>\\r\\n                            看看还有多少封单，别忽悠了，...</td>\n",
       "      <td>2018-06-22  09:47:31</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>344</td>\n",
       "      <td>博傻开始</td>\n",
       "      <td>2018/6/22 9:35</td>\n",
       "      <td>今天半仓，明天低开全仓</td>\n",
       "      <td>（25）</td>\n",
       "      <td>\\r\\n                            今天打不开吧？这么大的压单\\...</td>\n",
       "      <td>2018-06-22  09:40:28</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>345</td>\n",
       "      <td>窒息</td>\n",
       "      <td>2018/6/22 11:58</td>\n",
       "      <td>110万资金惨遭七连跌的杀戮，只剩下51万，赤裸裸的屠杀</td>\n",
       "      <td>（2）</td>\n",
       "      <td>\\r\\n                            能剩1万算你牛！\\r\\n  ...</td>\n",
       "      <td>2018-06-22  15:38:35</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>346</td>\n",
       "      <td>亏大了一一一被平仓一一一也平不掉</td>\n",
       "      <td>2018/6/22 12:46</td>\n",
       "      <td>000063：5万自己的加5万荣资的，现在都是卷商的还卖不掉，还在吹我加钱吖</td>\n",
       "      <td>（3）</td>\n",
       "      <td>\\r\\n                            偷鸡不成蚀把米啊，你想着赚更...</td>\n",
       "      <td>2018-06-22  12:59:25</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    Id                  title             time  \\\n",
       "0  334      蝴蝶效应啊，国家队就不能伸出援手吗   2018/6/22 9:34   \n",
       "1  341  根据港股跌幅计算，中兴通讯今天明天必开板。   2018/6/22 9:42   \n",
       "2  344                   博傻开始   2018/6/22 9:35   \n",
       "3  345                     窒息  2018/6/22 11:58   \n",
       "4  346       亏大了一一一被平仓一一一也平不掉  2018/6/22 12:46   \n",
       "\n",
       "                                  content replay  \\\n",
       "0                       蝴蝶效应啊，国家队就不能伸出援手吗    （2）   \n",
       "1                   根据港股跌幅计算，中兴通讯今天明天必开板。    （3）   \n",
       "2                             今天半仓，明天低开全仓   （25）   \n",
       "3            110万资金惨遭七连跌的杀戮，只剩下51万，赤裸裸的屠杀    （2）   \n",
       "4  000063：5万自己的加5万荣资的，现在都是卷商的还卖不掉，还在吹我加钱吖    （3）   \n",
       "\n",
       "                                          all_replay                time.1  \\\n",
       "0  \\r\\n                            救不起呀\\r\\n      ...  2018-06-22  09:45:00   \n",
       "1  \\r\\n                            看看还有多少封单，别忽悠了，...  2018-06-22  09:47:31   \n",
       "2  \\r\\n                            今天打不开吧？这么大的压单\\...  2018-06-22  09:40:28   \n",
       "3  \\r\\n                            能剩1万算你牛！\\r\\n  ...  2018-06-22  15:38:35   \n",
       "4  \\r\\n                            偷鸡不成蚀把米啊，你想着赚更...  2018-06-22  12:59:25   \n",
       "\n",
       "   label  \n",
       "0      0  \n",
       "1      0  \n",
       "2      0  \n",
       "3      0  \n",
       "4      0  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir = \"../data/12/\"\n",
    "stopwords=pd.read_csv( \"./stopwords.txt\",index_col=False,quoting=3,sep=\"\\t\",names=['stopword'], encoding='utf-8')\n",
    "stopwords=stopwords['stopword'].values\n",
    "df_data1 = pd.read_csv(dir+\"data1.csv\",encoding='utf-8')\n",
    "df_data1.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 接着进行数据预处理，把消极、中性、积极分别为0、1、2的预料分别拿出来："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#把内容有缺失值的删除\n",
    "df_data1.dropna(inplace=True)\n",
    "#抽取文本数据和标签\n",
    "data_1 = df_data1.loc[:,['content','label']]\n",
    "#把消极  中性  积极分别为0、1、2的预料分别拿出来\n",
    "data_label_0 = data_1.loc[data_1['label'] ==0,:]\n",
    "data_label_1 = data_1.loc[data_1['label'] ==1,:]\n",
    "data_label_2 = data_1.loc[data_1['label'] ==2,:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#定义分词函数\n",
    "def preprocess_text(content_lines, sentences, category):\n",
    "    for line in content_lines:\n",
    "        try:\n",
    "            segs=jieba.lcut(line)\n",
    "            segs = filter(lambda x:len(x)>1, segs)\n",
    "            segs = [v for v in segs if not str(v).isdigit()]#去数字\n",
    "            segs = list(filter(lambda x:x.strip(), segs)) #去左右空格\n",
    "            segs = filter(lambda x:x not in stopwords, segs)\n",
    "            temp = \" \".join(segs)\n",
    "            if(len(temp)>1):\n",
    "                sentences.append((temp, category))\n",
    "        except Exception:\n",
    "            print(line)\n",
    "            continue "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取数据\n",
    "data_label_0_content = data_label_0['content'].values.tolist()\n",
    "data_label_1_content = data_label_1['content'].values.tolist()\n",
    "data_label_2_content = data_label_2['content'].values.tolist()\n",
    "#生成训练数据\n",
    "sentences = []\n",
    "preprocess_text(data_label_0_content, sentences, 0)\n",
    "preprocess_text(data_label_1_content, sentences, 1)\n",
    "preprocess_text(data_label_2_content, sentences,2)\n",
    "#我们打乱一下顺序，生成更可靠的训练集\n",
    "random.shuffle(sentences)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#所以把原数据集分成训练集的测试集，咱们用sklearn自带的分割函数。\n",
    "from sklearn.model_selection import train_test_split\n",
    "x, y = zip(*sentences)\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3,random_state=1234)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CountVectorizer(analyzer='word', binary=False, decode_error='strict',\n",
       "        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',\n",
       "        lowercase=True, max_df=1.0, max_features=4000, min_df=1,\n",
       "        ngram_range=(1, 1), preprocessor=None, stop_words=None,\n",
       "        strip_accents=None, token_pattern='(?u)\\\\b\\\\w\\\\w+\\\\b',\n",
       "        tokenizer=None, vocabulary=None)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#抽取特征，我们对文本抽取词袋模型特征\n",
    "from sklearn.feature_extraction.text import CountVectorizer\n",
    "vec = CountVectorizer(\n",
    "    analyzer='word', #tokenise by character ngrams\n",
    "    max_features=4000,  #keep the most common 1000 ngrams\n",
    ")\n",
    "vec.fit(x_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 设置参数\n",
    "max_features = 5001\n",
    "maxlen = 100\n",
    "batch_size = 32\n",
    "embedding_dims = 50\n",
    "filters = 250\n",
    "kernel_size = 3\n",
    "hidden_dims = 250\n",
    "epochs = 10\n",
    "nclasses = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x_train shape: (1912, 100)\n",
      "x_test shape: (820, 100)\n"
     ]
    }
   ],
   "source": [
    "x_train = vec.transform(x_train)\n",
    "x_test = vec.transform(x_test)\n",
    "x_train = x_train.toarray()\n",
    "x_test = x_test.toarray()\n",
    "y_train = np_utils.to_categorical(y_train,nclasses)\n",
    "y_test = np_utils.to_categorical(y_test,nclasses)\n",
    "x_train = sequence.pad_sequences(x_train, maxlen=maxlen)\n",
    "x_test = sequence.pad_sequences(x_test, maxlen=maxlen)\n",
    "print('x_train shape:', x_train.shape)\n",
    "print('x_test shape:', x_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class LossHistory(keras.callbacks.Callback):\n",
    "    def on_train_begin(self, logs={}):\n",
    "        self.losses = {'batch':[], 'epoch':[]}\n",
    "        self.accuracy = {'batch':[], 'epoch':[]}\n",
    "        self.val_loss = {'batch':[], 'epoch':[]}\n",
    "        self.val_acc = {'batch':[], 'epoch':[]}\n",
    "\n",
    "    def on_batch_end(self, batch, logs={}):\n",
    "        self.losses['batch'].append(logs.get('loss'))\n",
    "        self.accuracy['batch'].append(logs.get('acc'))\n",
    "        self.val_loss['batch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['batch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def on_epoch_end(self, batch, logs={}):\n",
    "        self.losses['epoch'].append(logs.get('loss'))\n",
    "        self.accuracy['epoch'].append(logs.get('acc'))\n",
    "        self.val_loss['epoch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['epoch'].append(logs.get('val_acc'))\n",
    "\n",
    "    def loss_plot(self, loss_type):\n",
    "        iters = range(len(self.losses[loss_type]))\n",
    "        plt.figure()\n",
    "        # acc\n",
    "        plt.plot(iters, self.accuracy[loss_type], 'r', label='train acc')\n",
    "        # loss\n",
    "        plt.plot(iters, self.losses[loss_type], 'g', label='train loss')\n",
    "        if loss_type == 'epoch':\n",
    "            # val_acc\n",
    "            plt.plot(iters, self.val_acc[loss_type], 'b', label='val acc')\n",
    "            # val_loss\n",
    "            plt.plot(iters, self.val_loss[loss_type], 'k', label='val loss')\n",
    "        plt.grid(True)\n",
    "        plt.xlabel(loss_type)\n",
    "        plt.ylabel('acc-loss')\n",
    "        plt.legend(loc=\"upper right\")\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Build model...\n",
      "Train on 1912 samples, validate on 820 samples\n",
      "Epoch 1/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.4407 - acc: 0.8985 - val_loss: 0.3951 - val_acc: 0.9098\n",
      "Epoch 2/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3656 - acc: 0.9142 - val_loss: 0.4260 - val_acc: 0.9098\n",
      "Epoch 3/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3520 - acc: 0.9142 - val_loss: 0.4618 - val_acc: 0.9098\n",
      "Epoch 4/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3566 - acc: 0.9142 - val_loss: 0.4378 - val_acc: 0.9098\n",
      "Epoch 5/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3541 - acc: 0.9142 - val_loss: 0.4550 - val_acc: 0.9098\n",
      "Epoch 6/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3531 - acc: 0.9142 - val_loss: 0.4578 - val_acc: 0.9098\n",
      "Epoch 7/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3586 - acc: 0.9142 - val_loss: 0.4240 - val_acc: 0.9098\n",
      "Epoch 8/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3572 - acc: 0.9142 - val_loss: 0.4270 - val_acc: 0.9098\n",
      "Epoch 9/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3515 - acc: 0.9142 - val_loss: 0.5181 - val_acc: 0.9098\n",
      "Epoch 10/10\n",
      "1912/1912 [==============================] - 2s 1ms/step - loss: 0.3581 - acc: 0.9142 - val_loss: 0.4421 - val_acc: 0.9098\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x133edcdd8>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "history = LossHistory()\n",
    "print('Build model...')\n",
    "model = Sequential()\n",
    "\n",
    "model.add(Embedding(max_features,\n",
    "                        embedding_dims,\n",
    "                        input_length=maxlen))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Conv1D(filters,\n",
    "                     kernel_size,\n",
    "                     padding='valid',\n",
    "                     activation='relu',\n",
    "                     strides=1))\n",
    "model.add(GlobalMaxPooling1D())\n",
    "model.add(Dense(hidden_dims))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dense(nclasses))\n",
    "model.add(Activation('softmax'))\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "                  optimizer='adam',\n",
    "                  metrics=['accuracy'])\n",
    "model.fit(x_train, y_train,\n",
    "              batch_size=batch_size,\n",
    "              epochs=epochs,\n",
    "              validation_data=(x_test, y_test),callbacks=[history])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
